Sleep Unit
Source File: rtl/cv32e40p_sleep_unit.sv
The Sleep Unit contains and controls the instantiated clock gate, see Clock Gating Cell, that gates clk_i
and produces a gated clock
for use by the other modules inside CV32E40P. The Sleep Unit is the only place in which clk_i
itself is used; all
other modules use the gated version of clk_i
.
The clock gating in the Sleep Unit is impacted by the following:
rst_ni
fetch_enable_i
wfi instruction (only when
PULP_CLUSTER
= 0)cv.elw instruction (only when
PULP_CLUSTER
= 1)
pulp_clock_en_i
(only whenPULP_CLUSTER
= 1)
Table 10 describes the Sleep Unit interface.
Signal |
Direction |
Description |
---|---|---|
|
input |
|
|
||
|
output |
|
|
Note
The semantics of pulp_clock_en_i
and core_sleep_o
depend on the PULP_CLUSTER
parameter.
Startup behavior
clk_i
is internally gated off (while signaling core_sleep_o
= 0) during CV32E40P startup:
clk_i
is internally gated off duringrst_ni
assertion
clk_i
is internally gated off fromrst_ni
deassertion untilfetch_enable_i
= 1
After initial assertion of fetch_enable_i
, the fetch_enable_i
signal is ignored until after a next reset assertion.
WFI
The wfi instruction can under certain conditions be used to enter sleep mode awaiting a locally enabled interrupt to become pending. The operation of wfi is unaffected by the global interrupt bits in mstatus.
A wfi will not enter sleep mode, but will be executed as a regular nop, if any of the following conditions apply:
debug_req_i
= 1 or a debug request is pendingThe core is in debug mode
The core is performing single stepping (debug)
The core has a trigger match (debug)
PULP_CLUSTER
= 1
If a wfi causes sleep mode entry, then core_sleep_o
is set to 1 and clk_i
is gated off internally. clk_i
is
allowed to be gated off externally as well in this scenario. A wake-up can be triggered by any of the following:
A locally enabled interrupt is pending
A debug request is pending
Core is in debug mode
Upon wake-up core_sleep_o
is set to 0, clk_i
will no longer be gated internally, must not be gated off externally, and
instruction execution resumes.
If one of the above wake-up conditions coincides with the wfi instruction, then sleep mode is not entered and core_sleep_o
will not become 1.
Figure 9 shows an example waveform for sleep mode entry because of a wfi instruction.
PULP Cluster Extension
CV32E40P has an optional extension to enable its usage in a PULP Cluster in the PULP (Parallel Ultra Low Power) platform.
This extension is enabled by setting the PULP_CLUSTER
parameter to 1. The PULP platform is organized as clusters of
multiple (typically 4 or 8) CV32E40P cores that share a tightly-coupled data memory, aimed at running digital signal processing
applications efficiently.
The mechanism via which CV32E40P cores in a PULP Cluster synchronize with each other is implemented via the custom cv.elw instruction
that performs a read transaction on an external Event Unit (which for example implements barriers and semaphores). This
read transaction to the Event Unit together with the core_sleep_o
signal inform the Event Unit that the CV32E40P is not busy and
ready to go to sleep. Only in that case the Event Unit is allowed to set pulp_clock_en_i
to 0, thereby gating off clk_i
internal to the core. Once the CV32E40P core is ready to start again (e.g. when the last core meets the barrier), pulp_clock_en_i
is
set to 1 thereby enabling the CV32E40P to run again.
If the PULP Cluster extension is not used (PULP_CLUSTER
= 0), the pulp_clock_en_i
signal is not used and should be tied to 0.
Execution of a cv.elw instructions causes core_sleep_o
= 1 only if all of the following conditions are met:
The cv.elw did not yet complete (which can be achieved by witholding
data_gnt_i
and/ordata_rvalid_i
)No debug request is pending
The core is not in debug mode
The core is not single stepping (debug)
The core does not have a trigger match (debug)
As pulp_clock_en_i
can directly impact the internal clock gate, certain requirements are imposed on the environment of CV32E40P
in case PULP_CLUSTER
= 1:
If
core_sleep_o
= 0, thenpulp_clock_en_i
must be 1If
pulp_clock_en_i
= 0, thenirq_i[]
must be 0If
pulp_clock_en_i
= 0, thendebug_req_i
must be 0If
pulp_clock_en_i
= 0, theninstr_rvalid_i
must be 0If
pulp_clock_en_i
= 0, theninstr_gnt_i
must be 0If
pulp_clock_en_i
= 0, thendata_rvalid_i
must be 0If
pulp_clock_en_i
= 0, thendata_gnt_i
must be 0
Figure 10 shows an example waveform for sleep mode entry because of a cv.elw instruction.