LED Blinking FSM on a CPLD

 We’ll design a 3-state machine that controls an LED in different modes:



  1. OFF → LED is off.

  2. SLOW_BLINK → Toggles LED every 1 second.

  3. FAST_BLINK → Toggles LED every 0.25 seconds.

Hardware Setup

  • CPLD Board: Xilinx CoolRunner-II (XC2C256) or Lattice MachXO2.

  • Clock: Assume 12 MHz oscillator (adjustable for timing).

  • Inputs: A button (btn) to cycle through states.

  • Outputs: One LED (led) for blinking.


Step 1: VHDL Code for the State Machine

vhdl
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity LED_Controller is
    Port (
        clk     : in  STD_LOGIC;   -- 12 MHz clock
        btn     : in  STD_LOGIC;   -- Button to change state
        led     : out STD_LOGIC    -- Output LED
    );
end LED_Controller;

architecture Behavioral of LED_Controller is
    -- Define states
    type state_type is (OFF, SLOW_BLINK, FAST_BLINK);
    signal current_state, next_state : state_type := OFF;
    
    -- Counter for timing (12 MHz → 1 sec needs 12,000,000 cycles)
    signal counter : STD_LOGIC_VECTOR(23 downto 0) := (others => '0');
    signal blink_toggle : STD_LOGIC := '0';
begin
    -- State transition process
    process(clk)
    begin
        if rising_edge(clk) then
            -- Cycle states on button press (debounce omitted for simplicity)
            if btn = '1' then
                case current_state is
                    when OFF => next_state <= SLOW_BLINK;
                    when SLOW_BLINK => next_state <= FAST_BLINK;
                    when FAST_BLINK => next_state <= OFF;
                end case;
            else
                next_state <= current_state;
            end if;
            
            -- Update current state
            current_state <= next_state;
            
            -- Counter for blinking
            counter <= counter + 1;
        end if;
    end process;

    -- Blink control logic
    process(current_state, counter, blink_toggle)
    begin
        case current_state is
            when OFF =>
                led <= '0';  -- LED off
                blink_toggle <= '0';
            
            when SLOW_BLINK =>
                -- Toggle every 12,000,000 cycles (1 sec @ 12 MHz)
                if counter = X"B71B00" then  -- Hex for 12,000,000
                    blink_toggle <= not blink_toggle;
                    counter <= (others => '0');
                end if;
                led <= blink_toggle;
            
            when FAST_BLINK =>
                -- Toggle every 3,000,000 cycles (0.25 sec @ 12 MHz)
                if counter = X"2DC6C0" then  -- Hex for 3,000,000
                    blink_toggle <= not blink_toggle;
                    counter <= (others => '0');
                end if;
                led <= blink_toggle;
        end case;
    end process;
end Behavioral;

Step 2: Synthesis & Programming

  1. Synthesize the code in:

    • Xilinx ISE (for CoolRunner-II)

    • Lattice Diamond (for MachXO2)

  2. Assign pins (check your board’s schematic):

    • clk → Connect to oscillator (e.g., Pin 12).

    • btn → Connect to a push button (e.g., Pin 45).

    • led → Connect to an LED (e.g., Pin 67).

  3. Generate programming file (.jed for CPLD) and flash it.


Expected Behavior

  • Press the button to cycle through:

    • OFF → LED stays off.

    • SLOW_BLINK → LED toggles every 1 second.

    • FAST_BLINK → LED toggles every 0.25 seconds.


Key Takeaways

  1. SMC in CPLDs is ideal for low-latency control (vs. software-based FSMs).

  2. Debouncing (not shown here) should be added for real-world button inputs.

  3. Timing adjustments depend on the CPLD’s clock speed.

评论

此博客中的热门博文

Detailed Explanation of STM32 HAL Library Clock System

How To Connect Stm32 To PC?

How to add a GPS sensor to ESP32 for Wokwi?