When a wfi instruction is executed to enter
sleep mode and MicroBlaze V has completed all external
accesses, the pipeline is halted and the sleep,
hibernate, or suspend output signal is set.
This indicates to external hardware that it is safe to perform actions
such as stopping the clock, resetting the processor or other IP cores. Different actions
can be performed depending on which output signal is set. To wake up MicroBlaze V when in sleep mode, one (or both) of the Wakeup input signals must be set to one. In this case MicroBlaze V continues execution after the wfi instruction.
The Dbg_Wakeup output signal from MicroBlaze V indicates that the debugger requests a wake
up. External hardware should handle this signal and wake up the processor, after
performing any other necessary hardware actions such as starting the clock. If debug
wake up is used, the software must be aware that this could be the reason for waking up,
and go to sleep again if no other action is required.
In the simplest case, where no additional actions are needed before waking up
the processor, one of the Wakeup inputs can be
connected to the same signal as the MicroBlaze V
Interrupt input, and the other to the MicroBlaze
Dbg_Wakeup output. This allows MicroBlaze V to wake up when an interrupt occurs, or when the debugger
requests it.
For full compliance with the RISC-V Instruction Set Manual, the external interrupt input should be
connected to one of the Wakeup signals.
The block diagram in the following figure illustrates how to use the sleep functionality to implement clock control. In this example, the clock is stopped when sleep is executed and any interrupt or debug command enables the clock and wakes the processor.
library IEEE;
use IEEE.STD_LOGIC_1164.all;
library UNISIM;
use UNISIM.VComponents.all;
entity clock_control is
port (
clkin : in std_logic;
reset : in std_logic;
sleep : in std_logic;
interrupt : in std_logic;
dbg_wakeup : in std_logic;
clkout : out std_logic
);
end clock_control;
architecture Behavioral of clock_control is
attribute X_INTERFACE_INFO : string;
attribute X_INTERFACE_INFO of clkin : signal
is "xilinx.com:signal:clock:1.0 clk CLK";
attribute X_INTERFACE_INFO of reset : signal
is "xilinx.com:signal:reset:1.0 reset RST";
attribute X_INTERFACE_INFO of interrupt : signal
is "xilinx.com:signal:interrupt:1.0 interrupt INTERRUPT";
attribute X_INTERFACE_INFO of clkout : signal
is "xilinx.com:signal:clock:1.0 clk_out CLK";
attribute X_INTERFACE_PARAMETER : string;
attribute X_INTERFACE_PARAMETER of reset : signal
is "POLARITY ACTIVE_HIGH";
attribute X_INTERFACE_PARAMETER of interrupt : signal
is "SENSITIVITY LEVEL_HIGH";
attribute X_INTERFACE_PARAMETER of clkout : signal
is "FREQ_HZ 100000000";
signal clk_enable : std_logic := '1';
begin
clock_enable_dff : process (clkin) is
begin
if clkin'event and clkin = '1' then
if reset = '1' then
clk_enable <= '1';
elsif sleep = '1' and interrupt = '0' and dbg_wakeup = '0' then
clk_enable <= '0';
elsif clk_enable = '0' then
clk_enable <= '1';
end if;
end if;
end process clock_enable_dff;
clock_enable : component BUFGCE
port map (
O => clkout,
CE => clk_enable,
I => clkin
);
end Behavioral;