← RTL Design Interviews

Interview Question · Code Writing

Divide by 3 with a 50% Duty Cycle

L1 JuniorL2 Mid-Levelclock dividersclocks
  • Asked at Texas Instruments

The Question

The interviewer asks

Write RTL that divides a clock by 3 and gives a 50% duty cycle.

Reveal the Model Answer

A posedge counter that goes 0, 1, 2 can only make edges at whole input periods. So make a pulse q_pos that is high for one period in three. Copy it with a flop on the falling edge, so q_neg is the same pulse half a period later. Then q_pos | q_neg is high for 1.5 periods and low for 1.5. That is 50%, as long as the input clock is 50%.

Divide by 3 from a 50% input (10 ns period)
0123456clkq_posq_negclk_out

Each column is 5 ns, half an input period, from 0 to 30 ns. The output is high from 0 to 15 ns and low from 15 to 30 ns, as the run measures.

  1. Count on the rising edge

    cnt goes 0, 1, 2, 0. q_pos is high in the period after cnt is 2.

  2. Delay by half a period

    A falling-edge flop copies q_pos into q_neg.

  3. OR them

    q_pos covers 0 to T and q_neg covers T/2 to 1.5T, so the output is high from 0 to 1.5T.

A 10 ns input clock; the output high and low times are measured on the last full cycle.

RUNIcarus Verilog · in your browser
Edit the code, then run it
Expected: input 10 ns (high 5 ns): output high 15.0 ns, low 15.0 ns PASS: 1.5 input periods high and 1.5 low, a 50% duty cycle

Self-Check

Tick each key point you covered in your answer.

What Interviewers Listen For (Junior)

A good junior answer first says why a design that uses only rising edges cannot reach 50% for an odd ratio. It then draws q_pos, q_neg and their OR on one timeline.

Cross-Questions

Where the interviewer goes next. Open a node to practise that follow-up.

WhyWhat IfBreak ItCompare

  1. Divide by 3 with a 50% Duty Cycle
  2. CompareEven vs Odd Clock DivisionL0 FresherL1 Junior

    Compare dividing by an even number with dividing by an odd one. Show divide by 2 and divide by 4.

    Reveal the Model Answer

    An even divider toggles one flop every N/2 input periods, so its output is 50% with rising edges only. Divide by 2 is one flop with q <= ~q. Divide by 4 toggles every second edge. An odd ratio cannot split into equal halves of whole periods, so it needs the falling edge too.

    RUNIcarus Verilog · in your browser
    Edit the code, then run it
    Expected: divide by 2: period 20.0 ns, high 10.0 ns divide by 4: period 40.0 ns, high 20.0 ns

    Self-Check

    Tick each key point you covered in your answer.

    Half-Truth

    "Divide by 2 needs a counter."

    One flop that feeds back its own inverse already toggles at half the input rate.

  3. WhyWhy the 50% Divide by 3 Needs the Falling EdgeL1 Junior

    Why does the 50% divide-by-3 need a flop on the falling edge?

    Reveal the Model Answer

    The output must be high for 1.5 input periods. Rising edges come only at whole periods, so no rising-edge logic can end a pulse halfway. The falling edge is the only other edge that the input clock gives you.

    Self-Check

    Tick each key point you covered in your answer.

    Buzzword Without Mechanism

    Adds a delay cell to shift the pulse by half a period.

    A cell delay changes with process, voltage and temperature. The falling edge tracks the input clock itself.

  4. What IfWhen the Input Clock Is Not 50%L1 JuniorL2 Mid-Level

    What if the input clock is high for only 40% of its period?

    Reveal the Model Answer

    The falling-edge flop now delays the pulse by the input's high time, 4 ns instead of 5. So the output is high 14 ns and low 16 ns. The 50% divide-by-3 only promises 50% when the input is 50%.

    Divide by 3 from a 40% input (10 ns period)
    0123456clkq_posq_negclk_out

    Each column is an event time: 0, 4, 10, 14, 20, 24 and 30 ns. The output is high from 0 to 14 ns and low from 14 to 30 ns.

    Self-Check

    Tick each key point you covered in your answer.

    Misconception

    "The negedge flop delays by exactly half a period."

    It delays to the next falling edge, which comes after the input's high time. That equals half a period only for a 50% input.

    Source Measured: the twin on design.clkdiv.divide-by-3 (the 40% duty twin), Icarus Verilog 12

  5. Break ItWhat Breaks When a Divided Clock Drives FlopsL2 Mid-Level

    Break it: this divided clock now drives a bank of flops on an ASIC. What goes wrong if nobody tells STA?

    Reveal the Model Answer

    STA sees flops whose clock pin comes from logic, not from a defined clock. It reports them as unclocked and does not time their paths. Declare the output with create_generated_clock, or better, keep one clock and use an enable. The divider flops also add delay that clock-tree tools must balance.

    Self-Check

    Tick each key point you covered in your answer.

    Tool as Truth

    "STA will work out the divided clock by itself."

    In the L2.6 measurement, a divider with only create_clock left two flop clock pins unclocked. A generated clock had to be declared.

    Source Lesson L2.6, measured with OpenROAD (OpenSTA 3.1.0) on sky130hd, 2026-11-03

What People Get Wrong

Common wrong answers and why they fail. Run It shows the wrong belief failing on a real simulator.

Misconception

Counts to 3 on the rising edge and calls the result divide by 3 with 50% duty.

Rising edges come every period, so the output can only be high for one or two of the three periods. The twin measures 10 ns high and 20 ns low.

Run It

The same divider with the falling-edge flop left out.

RUNIcarus Verilog · in your browser
Edit the code, then run it
Expected: input 10 ns (high 5 ns): output high 10.0 ns, low 20.0 ns FAIL: a posedge-only divide by 3 is high one period in three, a 33% duty cycle
See the Fix
`timescale 1ns/1ps
module div3 (input logic clk, rst_n, output logic clk_out);
  logic [1:0] cnt;
  logic q_pos, q_neg;
  always_ff @(posedge clk or negedge rst_n)
    if (!rst_n) cnt <= 0; else cnt <= (cnt == 2) ? 2'd0 : cnt + 2'd1;
  always_ff @(posedge clk or negedge rst_n)        // high for one input period in three
    if (!rst_n) q_pos <= 0; else q_pos <= (cnt == 2);
  always_ff @(negedge clk or negedge rst_n)        // the same pulse, half a period later
    if (!rst_n) q_neg <= 0; else q_neg <= q_pos;
  assign clk_out = q_pos | q_neg;   // 1.5 periods high, 1.5 low
endmodule
module tb;
  logic clk = 0, rst_n = 0, clk_out;
  realtime t_rise = 0, t_fall = 0, hi = 0, lo = 0;
  int falls = 0;
  div3 d (.*);
  always begin clk = 1; #5; clk = 0; #5; end
  always @(posedge clk_out) begin if (falls > 0) lo = $realtime - t_fall; t_rise = $realtime; end
  always @(negedge clk_out) begin hi = $realtime - t_rise; t_fall = $realtime; falls++; end
  initial begin
    #12 rst_n = 1;
    #200;
    $display("input 10 ns (high 5 ns): output high %0.1f ns, low %0.1f ns", hi, lo);
    if (hi == lo) $display("PASS: 1.5 input periods high and 1.5 low, a 50%% duty cycle");
    $finish;
  end
endmodule

Prints: PASS: 1.5 input periods high and 1.5 low, a 50% duty cycle

Missed Corner

"The output is exactly 50% for any input clock."

The falling-edge flop delays by the input's high time, not by half a period. A 40% input gives 14 ns high and 16 ns low.

Run It

The 50% divider driven by a 40% duty input clock.

RUNIcarus Verilog · in your browser
Edit the code, then run it
Expected: input 10 ns (high 4 ns): output high 14.0 ns, low 16.0 ns FAIL: the output is 50% only when the input clock is 50%

Wrong Altitude

Draws the waveform but never says the output is a new clock.

The interviewer wants to hear what happens next. STA must know about it, and on an ASIC an enable is often better.

Learn It, Then Prove It