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.

评论

此博客中的热门博文

How To Connect Stm32 To PC?

What is a Look-Up Table (LUT) in an FPGA, and how does it work?

Detailed Explanation of STM32 HAL Library Clock System