ClockGate constructor
Constructs a clock gating block where enable
controls whether the
gatedClk is connected directly to the freeClk
or is gated off.
If controlIntf
is provided, then the clock gating can be controlled
externally (for example whether the clock gating isPresent or using an
override signal to force clocks enabled). If controlIntf
is not
provided, then the clock gating is always present.
If delayControlledSignals is true, then any signals that are controlled by the clock gating will be delayed by 1 cycle. This can be helpful for timing purposes to avoid ungating the clock on the same cycle as the signal is used. Using the controlled signals helps turn on or off the delay across all applicable signals via a single switch: delayControlledSignals.
The gatedClk is automatically enabled during reset
(if provided) so
that synchronous resets work properly, and the enable
is extended for an
appropriate duration (if delayControlledSignals) to ensure proper
capture of data.
Implementation
ClockGate(
Logic freeClk, {
required Logic enable,
Logic? reset,
ClockGateControlInterface? controlIntf,
this.delayControlledSignals = false,
super.name = 'clock_gate',
}) {
// if this clock gating is not intended to be present, then just do nothing
if (!(controlIntf?.isPresent ?? true)) {
_controlIntf = null;
gatedClk = freeClk;
return;
}
_freeClk = addInput('freeClk', freeClk);
_enable = addInput('enable', enable);
if (reset != null) {
_reset = addInput('reset', reset);
} else {
_reset = null;
}
if (controlIntf == null) {
// if we are not provided an interface, make our own to use with default
// configuration
_controlIntf = ClockGateControlInterface();
} else {
_controlIntf = ClockGateControlInterface.clone(controlIntf)
..pairConnectIO(this, controlIntf, PairRole.consumer);
}
gatedClk = addOutput('gatedClk');
_buildLogic();
}