Reduce power consumption in digital circuits
P_total = P_dynamic + P_static
P_dynamic = α × C × V² × f
α = Activity factor (switching probability)
C = Capacitance
V = Supply voltage
f = Clock frequency
P_static = I_leak × V
I_leak = Leakage current (transistors "off" but still leaking)
Turn off clock to unused logic. Most common power-saving technique.
// Bad: Clock runs even when data doesn't change
always @(posedge clk) begin
if (enable)
q <= d;
end
// Good: Let synthesis tool insert clock gating
// Most tools automatically convert the above to gated clock
// Explicit clock gating (if needed)
wire gated_clk;
assign gated_clk = clk & enable; // Simple but glitchy!
// Better: Latch-based clock gate (glitch-free)
module clock_gate (
input clk,
input enable,
output gated_clk
);
reg enable_latched;
// Latch enable on falling edge (when clock is low)
always @(clk or enable)
if (!clk)
enable_latched <= enable;
assign gated_clk = clk & enable_latched;
endmodule
Turn off power to unused blocks completely.
Special flip-flops that keep state even when power is off:
// Retention FF concept
// Before power-off: SAVE signal stores data to always-on register
// After power-on: RESTORE signal brings data back
// Tool handles this automatically with UPF/CPF
Use different threshold voltage transistors:
| Cell Type | Speed | Leakage | Use For |
|---|---|---|---|
| LVT (Low Vt) | Fast | High | Critical paths only |
| SVT (Standard) | Medium | Medium | Most logic |
| HVT (High Vt) | Slow | Low | Non-critical paths |
Lower voltage and frequency when full performance not needed.
Power ∝ V² × f
If you reduce V by 50% and f by 50%:
New power = (0.5)² × 0.5 = 0.125 = 12.5% of original!
Used in: Mobile processors, laptops
Different blocks run at different voltages:
Prevent unnecessary switching in datapath.
// Bad: Multiplier inputs toggle even when not used
always @(posedge clk) begin
if (mul_enable)
result <= a * b; // Multiplier sees a,b changes always
end
// Good: Isolate operands when not computing
wire [31:0] a_iso = mul_enable ? a : 32'b0;
wire [31:0] b_iso = mul_enable ? b : 32'b0;
always @(posedge clk) begin
if (mul_enable)
result <= a_iso * b_iso; // Inputs stable when disabled
end
// Memory is often the biggest power consumer!
1. Memory Banking
- Divide into banks, access only needed bank
2. Memory Shutdown
- Power off unused memory blocks
3. Retention Mode
- Ultra-low power mode that keeps data
// 1. Avoid unnecessary toggling
// Bad:
assign out = enable ? data : 32'hAAAA_AAAA; // Toggles when disabled!
// Good:
assign out = enable ? data : 32'b0; // Stable when disabled
// 2. Use one-hot encoding for low-activity signals
// Gray code for counters that cross clock domains
// 3. Minimize glitches
// Bad: Deep combinational logic with different path delays
// Good: Balance paths or add pipeline stages
// 4. Reset only what's needed
// Don't reset datapath registers if not needed
// 5. Use enable conditions
always @(posedge clk) begin
if (process_enable) begin
// Only do work when needed
result <= complex_operation(data);
end
end
1. RTL Simulation
└── Generate activity file (SAIF, VCD)
2. Synthesis
└── Map to standard cells
3. Power Analysis
└── Tool: PrimeTime PX, Voltus
└── Input: Netlist + Activity + Library
└── Output: Power report
Key metrics:
- Total power
- Leakage power
- Switching power
- Power by hierarchy/module
| Technique | Reduces | Complexity |
|---|---|---|
| Clock Gating | Dynamic | Low |
| Power Gating | Static + Dynamic | High |
| Multi-Vt | Static | Low |
| Voltage Scaling | Both | Medium |
| Operand Isolation | Dynamic | Low |