Back to Interview Prep

Verilog Interview Questions - Part 4: CDC & Advanced Design

June 3, 2026 HDL2Chips Team Verilog

This final part covers advanced design topics including clock domain crossing, reset strategies, pipelining, memory design, low-power techniques, DFT, and formal verification. These questions target senior and staff-level design roles.

Q31 Design a clock divider that converts a 250 MHz clock into a 1 ms output signal.

A 250 MHz clock has a period of 4 ns. A 1 ms output requires counting 250,000 clock cycles (1,000,000 ns / 4 ns = 250,000). For a 50% duty cycle, the counter toggles the output every 125,000 cycles. The counter must be wide enough to hold 124,999 — an 18-bit counter (2^17 = 131,072) suffices.

module clk_div_250m_to_1ms (
  input clk_250m, rst_n,
  output reg out_1ms
);
  reg [17:0] count;
  parameter MAX = 125000 - 1;

  always @(posedge clk_250m or negedge rst_n) begin
    if (!rst_n) begin
      count <= 0;
      out_1ms <= 0;
    end else if (count == MAX) begin
      count <= 0;
      out_1ms <= ~out_1ms;
    end else begin
      count <= count + 1;
    end
  end
endmodule
Q32 Design an enable signal that generates 250,000 states.

An enable signal that stays active for 250,000 clock cycles requires a counter that counts from 0 to 249,999. The enable output is asserted while the counter is within the counting range. This is commonly used for timing generation, state machine sequencing, or as a strobe for periodic operations. An 18-bit counter (2^18 = 262,144) is sufficient.

module enable_250k (
  input clk, rst_n,
  output reg enable
);
  reg [17:0] count;

  always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      count <= 0;
      enable <= 0;
    end else if (count < 250000 - 1) begin
      count <= count + 1;
      enable <= 1;
    end else begin
      enable <= 0;
    end
  end
endmodule

This enable signal pulses high for 250,000 consecutive cycles then goes low. Combined with a clock divider (Q31), it can create complex timing sequences for system-level control.

Q33 Design an up/down counter with parallel load.

An up/down counter can increment or decrement based on a direction control signal. Parallel load allows initializing the counter to a specific value. This is a fundamental building block in timer modules, address generators, and control logic.

module updown_counter #(parameter N = 8) (
  input clk, rst_n, up, down, load,
  input [N-1:0] d,
  output reg [N-1:0] count
);
  always @(posedge clk or negedge rst_n) begin
    if (!rst_n) count <= 0;
    else if (load) count <= d;
    else if (up && !down) count <= count + 1;
    else if (down && !up) count <= count - 1;
  end
endmodule
Q34 Design a Mod-N counter.

A Mod-N counter counts from 0 to N-1 and then wraps back to 0. The modulus is parameterized, making it reusable for different divide-by-N applications. The counter resets when it reaches the terminal count (N-1).

module mod_n_counter #(parameter N = 10) (
  input clk, rst_n, en,
  output reg [$clog2(N)-1:0] count,
  output reg tc
);
  always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin count <= 0; tc <= 0; end
    else if (en) begin
      if (count == N-1) begin count <= 0; tc <= 1; end
      else begin count <= count + 1; tc <= 0; end
    end else tc <= 0;
  end
endmodule
Q35 Design a D flip-flop using a 2x1 mux.

A D flip-flop can be constructed from a 2x1 multiplexer with feedback. The mux selects between the input D (when clk=1) and the current output Q (when clk=0), creating an edge-triggered behavior. This is a classic interview question testing understanding of sequential element construction from combinational logic.

module dff_mux (
  input clk, d,
  output reg q
);
  wire mux_out;
  assign mux_out = clk ? d : q;
  always @(*) q = mux_out;
endmodule

A more practical positive-edge-triggered DFF uses two cascaded mux-based latches (master-slave): the master is transparent when clk=0, the slave when clk=1. The rising edge captures the value because the slave latches the master's output exactly at the clock edge.

Q36 Design a clock divider that converts a 250 MHz clock to a 1 kHz signal with 75% duty cycle.

A 250 MHz clock has a period of 4 ns. 1 kHz = 1 ms period = 250,000 clock cycles. For 75% duty cycle, the output is high for 75% of 250,000 = 187,500 cycles and low for the remaining 62,500 cycles. This complements the 25% duty cycle design (Q40), showing how the same counter structure can produce different output waveforms.

module clk_div_75pct (
  input clk_250m, rst_n,
  output reg out_1k
);
  reg [17:0] count;
  parameter PERIOD = 250000 - 1;
  parameter HIGH = 187500 - 1;

  always @(posedge clk_250m or negedge rst_n) begin
    if (!rst_n) begin count <= 0; out_1k <= 0; end
    else begin
      if (count == PERIOD) count <= 0;
      else count <= count + 1;
      out_1k <= (count <= HIGH);
    end
  end
endmodule
Q37 Design a PWM generator with configurable duty cycle.

A PWM generator produces a variable-duty-cycle output by comparing a counter with a threshold value. When the counter is less than the threshold, the output is high; otherwise low. The counter resets at the period boundary.

module pwm_gen #(parameter N = 8) (
  input clk, rst_n,
  input [N-1:0] duty,
  output reg pwm_out
);
  reg [N-1:0] count;
  always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin count <= 0; pwm_out <= 0; end
    else begin
      count <= count + 1;
      pwm_out <= (count < duty);
    end
  end
endmodule
Q38 Design a Mealy FSM for a 1011 sequence detector.

A sequence detector asserts an output when the pattern "1011" is detected. In a Mealy machine, the output is asserted during the last bit of the sequence, allowing immediate response. Overlapping sequences are handled — after detecting "1011", the last "11" can start a new match.

module seq_1011 (
  input clk, rst_n, din,
  output reg detected
);
  reg [1:0] state;
  localparam S0 = 0, S1 = 1, S2 = 2, S3 = 3;
  always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin state <= S0; detected <= 0; end
    else begin
      detected <= 0;
      case (state)
        S0: if (din) state <= S1;
        S1: if (!din) state <= S2; else state <= S1;
        S2: if (din) state <= S3; else state <= S0;
        S3: begin
          if (din) begin state <= S1; detected <= 1; end
          else state <= S2;
        end
      endcase
    end
  end
endmodule
Q39 Design a T flip-flop using a 2x1 mux.

A T flip-flop toggles its output when T=1 and holds when T=0. Using a 2x1 mux, the mux selects between the current output Q (when T=0) and the inverted output ~Q (when T=1). This demonstrates how sequential elements with different behavior can be constructed from the same mux-based building block.

module tff_mux (
  input clk, t,
  output reg q
);
  wire mux_out;
  assign mux_out = t ? ~q : q;
  always @(posedge clk) q = mux_out;
endmodule
Q40 Design a clock divider that converts a 250 MHz clock to a 1 kHz signal with 25% duty cycle.

A 250 MHz clock has a period of 4 ns. 1 kHz = 1 ms period = 250,000 clock cycles. For 25% duty cycle, the output is high for 25% of 250,000 = 62,500 cycles and low for the remaining 187,500 cycles. A counter tracks the total period, and the output is asserted during the first 62,500 counts.

module clk_div_25pct (
  input clk_250m, rst_n,
  output reg out_1k
);
  reg [17:0] count;
  parameter PERIOD = 250000 - 1;
  parameter HIGH = 62500 - 1;

  always @(posedge clk_250m or negedge rst_n) begin
    if (!rst_n) begin count <= 0; out_1k <= 0; end
    else begin
      if (count == PERIOD) count <= 0;
      else count <= count + 1;
      out_1k <= (count <= HIGH);
    end
  end
endmodule

Counter, FSM, sequential logic, and clock dividers are the backbone of every digital design interview. Practice these patterns — clock dividers, counters with load/enable, FSMs for sequence detection and control, shift registers, and mux-based flip-flop construction — to build fluency for any design role.