Step-by-Step Guide: Designing a Low-Power UART Interface on a Xilinx CPLD

When your battery‑powered sensor node starts to die after a few weeks, you know it’s time to look at the tiny bits that waste power. The UART (Universal Asynchronous Receiver/Transmitter) is often the silent culprit—always listening, always driving. In this post I walk you through a practical, low‑power UART design on a Xilinx CPLD, using the same hands‑on style you’ll find on CPLD Insights.

Why Low Power Matters

Embedded designers wear many hats, but the one that never goes away is the “energy police” hat. Whether you are building a wearable, an IoT gateway, or a remote data logger, every microwatt counts. A UART that idles at full speed can drain a coin cell faster than you can say “sleep mode”. By trimming the UART’s power budget you extend battery life, reduce heat, and make your design more robust.

Picking the Right Xilinx CPLD

Xilinx offers several families of CPLDs: XC9500, XC9500XL, and the newer XC9500E. For low‑power work I prefer the XC9500E series because it supports fine‑grained clock gating and has a built‑in “Power‑Down” pin. The device also offers enough logic cells to implement a simple UART without resorting to an external transceiver.

Tip from the lab: I once tried to squeeze a full‑duplex UART into a tiny XC9500XL and ended up with a hot chip that smoked my breadboard. The lesson? Choose a device that gives you headroom for power‑saving tricks.

UART Basics in Plain Language

A UART is just a pair of shift registers that move bits in and out at a set baud rate. The transmitter takes parallel data, adds a start bit, optional parity, and stop bits, then shifts them out one by one. The receiver does the reverse, looking for the start bit, sampling the data, and checking parity if you use it.

Key parameters that affect power:

  • Baud rate – Higher speeds mean more switching activity.
  • Clock enable – Keeping the UART clock running when idle wastes power.
  • Logic depth – More gates toggling = more current.

Step 1: Define Your Requirements

Before you open Vivado or any other tool, write down the specs:

ParameterValue
Baud rate115200 (max)
Data bits8
ParityNone
Stop bits1
Power budget< 2 mW average
Supply voltage3.3 V

Having these numbers on paper helps you decide where you can cut corners. For example, if your application never needs 115 kbaud, you can lower the clock frequency and save a lot of power.

Step 2: Create a Clock Gating Scheme

The biggest power win comes from stopping the UART clock when the line is idle. Xilinx CPLDs let you gate the internal clock with a simple enable signal.

  1. Add a “UART Enable” register that is set when you have data to send or when a start bit is detected on the RX line.
  2. Feed this register into the clock enable pin of the UART’s internal shift registers.
  3. When the register is cleared, the clock stops toggling, and the shift registers hold their state without consuming dynamic power.

In VHDL the code looks like this (plain ASCII, no fancy characters):

process (clk)
begin
    if rising_edge(clk) then
        if uart_enable = '1' then
            uart_clk <= not uart_clk;
        else
            uart_clk <= '0';
        end if;
    end if;
end process;

The uart_enable flag is driven by two simple conditions: a transmit request or a detected start bit on the RX line.

Step 3: Implement a Low‑Power State Machine

A UART can be modeled as a small finite‑state machine (FSM). Keep the FSM tiny—four states are enough:

  • IDLE – Clock gated, waiting for activity.
  • START – Detect start bit, enable clock.
  • DATA – Shift in/out data bits.
  • STOP – Verify stop bit, then return to IDLE.

Because the FSM only changes state when needed, the switching activity stays low. Use synchronous reset to avoid glitches.

Step 4: Use a Low‑Power Baud Rate Generator

The baud rate generator is a simple counter that divides the system clock. To keep it low power:

  • Use a binary counter with the smallest width that still reaches your max baud rate.
  • Enable the counter only when uart_enable is high.
  • Reset the counter to zero in the IDLE state.

Here’s a concise VHDL snippet:

process (clk)
begin
    if rising_edge(clk) then
        if uart_enable = '1' then
            if baud_cnt = BAUD_MAX then
                baud_tick <= '1';
                baud_cnt <= (others => '0');
            else
                baud_tick <= '0';
                baud_cnt <= baud_cnt + 1;
            end if;
        else
            baud_tick <= '0';
            baud_cnt <= (others => '0');
        end if;
    end if;
end process;

The baud_tick pulse drives the shift registers only when needed, further reducing unnecessary toggling.

Step 5: Add a Pull‑Down on the RX Line

When the UART is idle, the RX pin can float and cause the CPLD to toggle its input buffer. Adding a weak pull‑down resistor (10 kΩ is fine) keeps the line at a known low level, preventing spurious start‑bit detection and saving power.

Step 6: Simulate Power Consumption

Before you solder the board, run a power simulation. Xilinx’s Power Analyzer can estimate dynamic power based on toggle rates. Feed it a realistic traffic pattern: a burst of 10 bytes, then 5 seconds of silence. Adjust the clock gating logic until the average power falls below your 2 mW target.

Step 7: Verify on Hardware

Load the bitstream onto a development board (the Xilinx XC9500E Evaluation Kit works well). Use a logic analyzer to watch the UART clock line. You should see the clock stop completely during idle periods. Measure the current with a low‑ohm shunt resistor; you’ll be surprised how low the number drops.

A quick anecdote: The first time I tried this on a real board, the UART kept waking up because I forgot to debounce the start‑bit detection. A simple two‑flip‑flop synchronizer solved it, and the power curve flattened nicely. Always remember that noisy edges can defeat even the best clock‑gating plan.

Step 8: Document and Reuse

Once you have a working low‑power UART, wrap it in a reusable VHDL package. Include parameters for baud rate, data width, and enable polarity. This way, future projects can drop the UART in without re‑engineering the power tricks.


Designing a low‑power UART on a Xilinx CPLD is not magic; it’s a series of small, thoughtful choices—clock gating, minimal logic, and careful reset handling. By following the steps above you’ll get a UART that sleeps soundly when not needed, extending the life of your battery‑powered designs.

Reactions
Do you have any feedback or ideas on how we can improve this page?