Chapter 04: Clocks, Timing & PLLs

Understanding the heartbeat of your FPGA

Why Clocks Matter

The clock is the global synchronizer. Every flip-flop updates on the clock edge. If your clock is wrong, EVERYTHING is wrong.

Clock Frequency = Speed of Computation
27 MHz clock = 27 million operations per second
1 GHz clock = 1 billion operations per second

Your Tang Primer 20K Clock

The board has a 27 MHz crystal oscillator connected to pin H11. This is your primary clock source.

// Using the board clock

module top (
    input clk_27mhz,     // 27 MHz from crystal
    output reg led
);

    reg [23:0] counter;

    always @(posedge clk_27mhz) begin
        counter <= counter + 1;
        led <= counter[23];  // Toggle LED every 2^23 clocks (~0.3s)
    end

endmodule

Clock Dividers: Creating Slower Clocks

Sometimes you need a slower clock. Use a counter to divide frequency:

// Divide 27 MHz by 27,000 to get 1 kHz

module clock_divider (
    input  clk_in,       // 27 MHz
    input  rst,
    output reg clk_out    // 1 kHz
);

    reg [14:0] counter;  // Need to count to 27,000

    always @(posedge clk_in) begin
        if (rst) begin
            counter <= 0;
            clk_out <= 0;
        end
        else if (counter == 13499) begin  // Half period
            counter <= 0;
            clk_out <= ~clk_out;  // Toggle
        end
        else
            counter <= counter + 1;
    end

endmodule
WARNING: Never use divided clocks directly as clock signals! This creates clock domain crossing issues. Instead, use the fast clock with an enable signal.

Clock Enable: The Right Way

// Use clock enable instead of divided clock

module clock_enable (
    input  clk,
    input  rst,
    output reg clk_enable  // Pulse every N clocks
);

    reg [14:0] counter;

    always @(posedge clk) begin
        if (rst) begin
            counter <= 0;
            clk_enable <= 0;
        end
        else if (counter == 26999) begin
            counter <= 0;
            clk_enable <= 1;  // Pulse high for one cycle
        end
        else begin
            counter <= counter + 1;
            clk_enable <= 0;
        end
    end

endmodule

// Using the enable signal
always @(posedge clk) begin
    if (clk_enable) begin
        // This code runs at 1 kHz
        my_counter <= my_counter + 1;
    end
end

PLLs: Phase-Locked Loops

Need a FASTER clock? Or a precise frequency? Use a PLL. It's a hardware frequency multiplier/divider.

PLL Example: Take 27 MHz input, multiply by 4, divide by 3 = 36 MHz output

Using Gowin PLL IP Core

  1. In Gowin IDE: Tools → IP Core Generator
  2. Select "PLL" (rPLL for GW2A devices)
  3. Configure:
    • Input frequency: 27 MHz
    • Output frequency: 108 MHz (or whatever you need)
    • Enable CLKOUTD if you need multiple clock outputs
  4. Name it Gowin_rPLL
  5. Generate

Instantiating the PLL

// Using PLL in your design

module top (
    input  clk_27mhz,
    output led
);

    wire clk_108mhz;
    wire pll_lock;     // PLL locked indicator

    // Instantiate PLL
    Gowin_rPLL pll_inst (
        .clkin(clk_27mhz),
        .clkout(clk_108mhz),
        .lock(pll_lock)
    );

    // Use the 108 MHz clock
    reg [25:0] counter;

    always @(posedge clk_108mhz) begin
        if (pll_lock)
            counter <= counter + 1;
    end

    assign led = counter[25];

endmodule

Timing Constraints

Tell the tools what clock frequency you're using so they can optimize routing:

// In your .sdc file (Synopsys Design Constraints)

// Primary clock: 27 MHz = 37.037 ns period
create_clock -name clk_27mhz -period 37.037 [get_ports {clk_27mhz}]

// Generated clock from PLL: 108 MHz = 9.259 ns period
create_generated_clock -name clk_108mhz -source [get_ports {clk_27mhz}] \
    -multiply_by 4 -divide_by 1 [get_nets {clk_108mhz}]

Clock Domain Crossing (CDC)

When signals cross between different clock domains, you need synchronizers to prevent metastability:

// 2-stage synchronizer for single-bit signals

module synchronizer (
    input  clk_dest,      // Destination clock
    input  async_in,       // Asynchronous input
    output reg sync_out   // Synchronized output
);

    reg sync_stage1;

    always @(posedge clk_dest) begin
        sync_stage1 <= async_in;    // First flop (may go metastable)
        sync_out <= sync_stage1;    // Second flop (stable output)
    end

endmodule
METASTABILITY: When a flip-flop samples a signal right as it's changing, the output can oscillate before settling. This is why we need 2 stages - first flop may glitch, second flop is stable.

Key Timing Concepts

TermMeaning
Setup TimeData must be stable BEFORE clock edge
Hold TimeData must be stable AFTER clock edge
Clock-to-QDelay from clock edge to output change
Max Frequency (Fmax)Fastest clock that meets all timing
SlackTime margin (positive = good, negative = BAD)

Practical Tips