9#ifndef CIRCT_DIALECT_FIRRTL_GATEDCLOCKCONVERSION_H
10#define CIRCT_DIALECT_FIRRTL_GATEDCLOCKCONVERSION_H
14#include "llvm/ADT/MapVector.h"
31 ClockGateIntrinsicOp
gate()
const {
return cast<ClockGateIntrinsicOp>(
op); }
32 InstanceOp
instance()
const {
return cast<InstanceOp>(
op); }
54 LogicalResult
addRoot(Operation *op);
87 assert(v &&
"use MatRef() for a null reference");
88 assert(!v.getDefiningOp<FInstanceLike>() &&
89 "instance results must be symbolic; use MatRef::instResult()");
112 if (
auto inst = v.getDefiningOp<FInstanceLike>())
113 return instResult(inst, cast<OpResult>(v).getResultNumber());
121 ClockGateIntrinsicOp
gate()
const {
return cast<ClockGateIntrinsicOp>(
op); }
123 void print(llvm::raw_ostream &os)
const;
136 Operation *
op =
nullptr;
219 MatRef baseClk,
unsigned enableId);
248 Value
lower(
unsigned enableId);
250 LogicalResult
rewriteRoot(Operation *op, Value baseClk, Value enable);
261 unsigned clkPortIndex,
262 unsigned enPortIndex,
263 Value materializedClk,
264 Value materializedEn);
274 return clone ? clone : inst;
281 void planAlias(Value dstClk, FModuleOp srcMod, MatRef baseClk,
284 void planGate(ClockGateIntrinsicOp gate, Value dstClk, MatRef baseClk,
288 Value srcClk, MatRef baseClk,
unsigned enableId);
296 std::pair<unsigned, unsigned>
297 planGatedPorts(InstanceOp inst, FModuleOp childMod,
unsigned gatedClkIndex,
298 Direction dir, MatRef baseClk,
unsigned enableId);
301 MatRef baseClk,
unsigned enableId);
305 SmallVector<std::pair<Operation *, Value>>
roots;
assert(baseType &&"element must be base type")
A reference to a clock/enable value that can also name values which do not exist yet (a planned port,...
unsigned index
Result, argument or wire index.
Operation * getOp() const
static MatRef direct(Value v)
ClockGateIntrinsicOp gate() const
Operation * op
Instance / module / gate, by kind.
static MatRef instResult(FInstanceLike inst, unsigned index)
void print(llvm::raw_ostream &os) const
static MatRef gateEnable(ClockGateIntrinsicOp gate)
@ PlannedWire
Entry index of plannedWireValues.
@ None
Null reference, e.g. "no enable".
@ ModuleArg
Block argument index of a module (existing or planned).
@ InstResult
Result index of an instance (existing or planned port).
@ GateEnable
gate.enable | gate.test_enable, lowered on demand.
@ Direct
A Value that applyPlan() never invalidates.
static MatRef of(Value v)
Instance results become symbolic refs, every other value is stable.
unsigned getIndex() const
static MatRef moduleArg(FModuleOp mod, unsigned index)
static MatRef opRef(Kind kind, Operation *op, unsigned index)
static MatRef plannedWire(unsigned index)
Sink gated-clock enables into ops across module boundaries.
DenseSet< Value > gatedClocks
void planInstancePort(Direction dir, InstanceOp inst, Value dstClk, Value srcClk, MatRef baseClk, unsigned enableId)
llvm::MapVector< FModuleOp, SmallVector< PortPlanKey > > plansPerModule
LogicalResult analyzeFrom(ArrayRef< Value > seeds)
void planMultiplyInstantiatedInput(Value srcClk, MatRef baseClk, unsigned enableId)
DenseMap< Operation *, Operation * > instClones
void recordInstanceDrive(InstanceOp inst, const PortPairPlan &plan, MatRef baseClk, unsigned enableId)
void planGate(ClockGateIntrinsicOp gate, Value dstClk, MatRef baseClk, unsigned enableId)
std::pair< unsigned, unsigned > planGatedPorts(InstanceOp inst, FModuleOp childMod, unsigned gatedClkIndex, Direction dir, MatRef baseClk, unsigned enableId)
DenseMap< ClockGateIntrinsicOp, Value > gateEnableCache
std::pair< FModuleOp, unsigned > PortPlanKey
The (module, clock port index) key of a PortPairPlan.
SmallVector< Value > baseClks
unsigned newEnableLeaf(MatRef term, Location loc)
void createPlannedWires()
void eliminateTemporaryWires()
GatedClockConversion(InstanceGraph &ig)
llvm::MapVector< PortPlanKey, PortPairPlan > portPlans
void planAlias(Value dstClk, FModuleOp srcMod, MatRef baseClk, unsigned enableId)
static constexpr unsigned kNoEnable
Sentinel EnableNode index meaning "no enable at all".
LogicalResult rewriteRoot(Operation *op, Value baseClk, Value enable)
SmallVector< WirePairPlan > wirePlans
void computeGatedClocks()
unsigned newEnableNode(unsigned parent, MatRef term, Location loc, MatRef anchor)
void connectMaterializedToInstancePorts(InstanceOp inst, unsigned clkPortIndex, unsigned enPortIndex, Value materializedClk, Value materializedEn)
llvm::MapVector< std::pair< InstanceOp, unsigned >, InstanceDrive > instanceDrives
Value getOrCreateConstU1One(FModuleOp mod)
LogicalResult addRoot(Operation *op)
LogicalResult emitPlannedIR()
DenseMap< FModuleOp, unsigned > nextPortIdx
SmallVector< RootRewrite > rootRewrites
SmallVector< Value > plannedWireValues
SmallVector< std::pair< Operation *, Value > > roots
SmallVector< EnableNode > enableNodes
DenseMap< Value, SmallVector< ClockEdge > > srcToDstClocks
SmallVector< WireOp > wireOps
DenseSet< Value > visited
Value gateEnableOf(ClockGateIntrinsicOp gate)
SmallVector< Value > loweredEnables
void insertPlannedPorts()
SmallVector< InstanceOp > deadInstances
DenseMap< Value, ClockPairPlan > clockEnablePairs
LogicalResult applyPlan()
Value processEdge(const ClockEdge &edge, Value srcClk, FModuleOp srcMod, MatRef baseClk, unsigned enableId)
Operation * liveInstance(Operation *inst) const
Value lower(unsigned enableId)
Value resolve(MatRef ref)
DenseMap< FModuleOp, Value > constU1Cache
This graph tracks modules and where they are instantiated.
Direction
This represents the direction of a single port.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
InstanceOp instance() const
ClockGateIntrinsicOp gate() const
(baseClk, enable) pair planned for a clock value.
Enable accumulation DAG node: value(id) = parent == kNoEnable ? term : (value(parent) & term) Nodes a...
MatRef anchor
Insert the and after this value.
Caller-side connects driving a planned input port pair.
unsigned enableId
kNoEnable drives a constant 1.
(baseClock, enable) port pair to append to a module.
MatRef outBaseClk
dir == Out only: values inside mod driving the new output ports.
unsigned gatedClkIndex
Clock port this pair shadows (naming only).
unsigned baseIdx
Final port indices, pre-assigned at planning time.
Root rewrite applied by applyPlan(): clock the op by baseClk and sink enableId into it.
Temporary (base clock, enable) carrier wires at the top of mod, standing in for a wire/node alias of ...