Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • How to Use This Course
  • Reading Paths
  • Concept Map
  • How to Read the Diagrams
  • Part 0: What Is a Protocol?10
  • Part 1: Timing and Clocking11
  • Part 2: Encoding and Framing12
  • Part 3: Handshakes13
  • Part 4: Flow Control17
  • Part 5: Transactions19
  • Part 6: Concurrency and Performance17
  • Part 7: Ordering13
  • Part 8: Sharing and Arbitration12
  • Part 9: Deadlock and Liveness13
  • Part 10: Reliability and Recovery20
  • Part 11: Bring-Up and Link Management10
  • Part 12: Power8
    • Idle Detection
    • Link Power States
    • Break-Even Time
    • Low-Power Handshakes
    • Quiescing and Draining
    • Wake Signalling
    • Protocols Compared: Power
    • Drills: Power
  • Part 13: Shared State and Coherence9
  • Part 14: Security and Isolation7
  • Part 15: Specifying and Verifying11
  • Part 16: Protocols Dissected17
  • Part 17: Capstones5
  • Part 18: Interview Preparation6
Loading lesson

‹Part 12: Power
  1. Topics
  2. First Principles of Hardware Protocols
  3. Part 12: Power
  4. Low-Power Handshakes

Part 12 · Power · Senior (S)

Low-Power Handshakes

A power controller must not switch off a device that is still working. The request, accept or deny handshake lets the device say whether it can sleep now. DCLink step 11, built and simulated, with the AMBA Q-Channel and P-Channel as the real examples.

On this page

    Note

    Level: Senior (S) · Answers: How do we save power without losing data?

    Before this: Break-Even Time, Two- and Four-Phase Req/Ack

    A system's power controller sees that a DMA engine has been quiet for a while and gates its clock. But the engine was not finished: it had issued a read whose data was still on its way back. The data arrives at a block with no clock, the engine never sees it, and the transfer hangs. The controller's view of "idle" was wrong, and the only party that knew better was never asked.

    How does a power controller ask a device to sleep without cutting it off in the middle of work?

    The obvious answer, and why it breaks

    The obvious design lets the controller decide alone and switch the clock or power off. The controller sees only the interfaces it watches; it cannot see a device's outstanding requests, its internal queues or work it is about to start. Only the device knows whether it can stop now. So entry into a low-power state must be a request the device can answer.

    The idea: request, then accept or deny

    • Request: the controller raises a request and holds it (a four-phase handshake, lesson 3.5).

    • Accept: if the device is idle and can stop, it finishes anything in progress, stops taking new work, and accepts. Only then may the controller gate its clock or remove power.

    • Deny: if the device is busy, it denies. The controller withdraws and tries later. Being able to deny is the point: the device can never be forced asleep mid-work.

    • Exit: the controller withdraws the request (or the device signals it needs to wake); the device leaves the state and resumes.

    Build it: DCLink step 11

    The device is busy in cycles 1 to 4. The controller asks in cycle 2 and is denied; it asks again in cycle 7, when the device is idle, and is accepted; it wakes the device in cycle 11.

    tb.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    // DCLink step 11: the low-power entry handshake. The power controller asks the
    // device to sleep by raising slp_req and holding it. The device answers with
    // slp_acc (it is idle: it stops taking work and sleeps) or slp_deny (it is busy).
    // On a deny the controller drops its request and tries later; to wake an accepted
    // device, it drops slp_req and the device drops slp_acc. Here the device is busy
    // in cycles 1 to 4: the first request (cycle 2) is denied, the second (cycle 7) is
    // accepted, and the controller wakes the device in cycle 11. The checker confirms
    // the device never accepted while busy and never answered both ways at once.
    module tb;
      logic clk = 0;
      always #5 clk = ~clk;
      initial begin $dumpfile("wave.vcd"); $dumpvars(0, tb); end
    
      int cyc = 0;
      always @(posedge clk) cyc <= cyc + 1;
    
      logic busy = 0, slp_req = 0, slp_acc = 0, slp_deny = 0;
      always @(posedge clk) busy <= (cyc >= 0 && cyc <= 3);   // outstanding work in cycles 1-4
    
      // Power controller
      always @(posedge clk) begin
        if (!slp_req && !slp_acc && !slp_deny && (cyc == 2 || cyc == 7)) slp_req <= 1;
        else if (slp_req && slp_deny) slp_req <= 0;              // denied: give up for now
        else if (slp_req && slp_acc && cyc == 11) slp_req <= 0;  // wake the device
      end
      // Device
      always @(posedge clk) begin
        if (slp_req && !slp_acc && !slp_deny) begin
          if (busy) slp_deny <= 1;
          else      slp_acc  <= 1;                              // idle: accept and sleep
        end
        else if (!slp_req) begin slp_deny <= 0; slp_acc <= 0; end
      end
    
      int accepts = 0, denies = 0, bad = 0;
      logic acc_q = 0, deny_q = 0;
      always @(posedge clk) begin
        acc_q <= slp_acc; deny_q <= slp_deny;
        if (slp_acc && !acc_q) begin accepts++; if (busy) bad++; end
        if (slp_deny && !deny_q) denies++;
        if (slp_acc && slp_deny) bad++;
      end
      initial begin
        #200;
        if (accepts == 1 && denies == 1 && bad == 0 && !slp_acc)
          $display("PASS: busy device denied the first request, accepted the second when idle, and woke on request");
        else $display("FAIL: accepts %0d denies %0d bad %0d acc %0d", accepts, denies, bad, slp_acc);
        $finish;
      end
    endmodule

    Watch it run

    How to read it, slot by slot:

    • Slots 0 to 3: the device is busy. The controller raises slp_req in slot 2.

    • Slot 3: the device answers slp_deny. Slot 4: the controller drops its request; slot 5: the device drops the deny. The handshake is closed and nothing was turned off.

    • Slot 7: a new request, with the device idle. Slot 8: slp_acc: the device is asleep and takes no work.

    • Slot 11: the controller drops slp_req to wake it; slot 12: slp_acc falls and the device is awake.

    The design space

    Choice

    Options

    Who starts

    Controller requests (most common); or the device asks to sleep

    Can the device refuse

    Accept or deny (safe, flexible); or accept only, after it finishes (simpler, but the controller may wait long)

    What it controls

    Clock gating only; or several power states, named in the request

    Wake

    Controller withdraws the request; and the device signals that it has new work

    How real protocols chose

    Protocol

    Low-power handshake

    AMBA Q-Channel

    QREQn (request, active low), QACCEPTn and QDENY from the device, and QACTIVE to show the device has work: for clock gating and simple power control.

    AMBA P-Channel

    PREQ with a requested PSTATE, answered by PACCEPT or PDENY, and PACTIVE hints: for choosing among several power states.

    PCI Express

    Device power states are set by software through configuration space; link states are negotiated between the two ends of the link.

    DCLink

    Step 11: slp_req, answered by slp_acc or slp_deny.

    What breaks

    The opening hang (illustrative) came from a clock-gating controller that watched only the DMA engine's request interface. Replacing it with a Q-Channel-style handshake, where the engine accepts only when its outstanding-read count is zero, removed the hang; the engine denied about one request in five, each time because a read was still in flight.

    Why this matters

    Senior lens. Never let a power controller remove a clock or power from a block that has not agreed. Give every power domain a request/accept/deny handshake, define exactly what "idle enough to accept" means for each block (outstanding requests, queues, owed credits), and verify the races: a request arriving at the device in the same cycle it accepts, and a wake request during entry.

    Interview

    Asked: "Why does a low-power handshake allow the device to deny?"

    Weak answer: So the device can stay on if it wants.

    Strong answer: Because only the device knows whether it can safely stop: it may have outstanding requests, data in its queues or work it's about to start, none of which the power controller can see. With request, accept or deny, the controller asks; the device accepts only after it has finished and stopped taking work, and denies if it's busy, so the controller backs off and retries. That makes it impossible to cut a block off mid-transaction. AMBA's Q-Channel does exactly this with QREQn, QACCEPTn and QDENY; the P-Channel adds a requested power state.

    Follow-ups: (1) What must the device do before accepting? (2) How is a sleeping device woken?

    Check yourself What must a device have done before it accepts a sleep request?

    Finished or drained its work, including outstanding requests, and stopped accepting new work.

    Check yourself In the simulation, why was nothing turned off after the first request?

    The device was busy and denied it; the controller withdrew, and no accept was ever given.

    Key takeaways

    • Only the device knows if it can stop; entry into low power must be a request it can answer.

    • The device accepts after finishing its work, or denies if busy; the controller acts only on an accept.

    • AMBA's Q-Channel and P-Channel are the standard examples; DCLink step 11 builds the same idea.

    Keep going

    Next: Lesson 12.5, Quiescing and Draining. Bringing an interface to a clean stop before its power goes.

    Related topics

    • Part 12 overview: Power

    Previous

    175 / 234

    Next: Quiescing and Draining

    Up next

    Up nextQuiescing and Draining

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Idle Detection
    • Link Power States
    • Wake Signalling
    clkbusyslp_reqslp_accslp_deny
    Simulation output: a busy device denies the first sleep request; the idle device accepts the second; dropping the request wakes it.