Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • RTL Foundations36
  • Combinational Design25
  • Sequential Design27
  • FSM & Control27
  • Timing & Clocking39
  • Reset & CDC34
  • Memory & Buses57
  • Advanced RTL28
  • Senior & Interview76
    • Low-Power RTL Hub
    • DFT and Scan Hub
      • Why scan exists
      • The scan chain at RTL abstraction
      • Test-mode integration checklist
      • Controllability and observability in practice
      • Fault Coverage by Hand
    • Physical Awareness Hub
    • Waveform Debug Hub
    • STA and ECO Hub
    • RTL-to-Implementation Closure
    • DFT-Ready RTL
    • Capstone: Resilient Streaming Peripheral
    • Principal Design Review
    • Senior RTL Interview Questions & Model Answers
  • Glossary and Notation
Loading lesson

‹DFT and Scan Hub
  1. Topics
  2. RTL Design
  3. Senior & Interview
  4. DFT and Scan Hub
  5. Controllability and observability in practice

Part 9 · Senior · Senior

Controllability and observability in practice

Safe test overrides for slow waits and sticky flags for rare events, both proven in simulation.

On this page

    Why this matters

    A long idle timeout needs hundreds of quiet cycles per pattern, which makes ATPG slow, while a test-mode mux on a security qualifier opens a hole for every pattern. One idiom helps the tool; the other breaks the design.

    After this lesson you can: shorten a wait in test mode only, make a rare event sticky, and explain why a guard signal never gets a test override.

    Shorten waits, do not bypass guards

    RTL coding decisions can make ATPG dramatically easier or harder. A long idle timeout is hard to control: reaching it needs hundreds of quiet cycles per pattern.

    The safe override shortens the wait in test mode only. It never touches enables that guard access, and it changes nothing when test mode is low.

    Test mode swaps the 300-cycle limit for 3 at the compare; the counter, the compare and done_o are the same in both modes

    Read the path left to right: only the limit input changes with test mode.

    • Without the override, every pattern that needs done_o must first spend 300 quiet cycles; with it, 3.

    • The counter, the compare and the done_o register are the same hardware in both modes, so test patterns exercise the real logic.

    • With test_mode_i low, the mux passes 300 and the block behaves exactly as before.

    The mode input must be synchronous to clk. The threshold applies to the elapsed continuous idle interval: lowering it below the elapsed count completes on the next edge, while raising it before completion extends the wait. Once done, completion stays set until idle falls or reset asserts. Both limits must be positive.

    idle_terminate.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    `timescale 1ns/1ps
    module idle_terminate #(
      parameter FUNC_LIMIT = 300,
      parameter TEST_LIMIT = 3
    ) (
      input  logic clk,
      input  logic rst_n,
      input  logic idle_i,
      input  logic test_mode_i,
      output logic done_o
    );
      localparam int MAXL = (FUNC_LIMIT > TEST_LIMIT) ? FUNC_LIMIT : TEST_LIMIT;
      logic [$clog2(MAXL+1)-1:0] idle_cnt, limit;
      assign limit = test_mode_i ? TEST_LIMIT : FUNC_LIMIT;
    
      initial begin
        if (FUNC_LIMIT < 1 || TEST_LIMIT < 1)
          $fatal(1, "idle_terminate: limits must be positive");
      end
    
      always_ff @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
          idle_cnt <= '0;
          done_o   <= 1'b0;
        end else if (!idle_i) begin
          idle_cnt <= '0;
          done_o   <= 1'b0;
        end else if (done_o || idle_cnt >= limit - 1'b1) begin
          done_o <= 1'b1;
        end else begin
          idle_cnt <= idle_cnt + 1'b1;
          done_o   <= 1'b0;
        end
      end
    endmodule

    Warning

    Never override a security or access qualifier with test mode. Forcing a guarded enable high in test mode defeats the guard for every pattern. Shortening a delay is safe; bypassing a permission check needs a separate, reviewed test path.

    Make rare events sticky

    A one-cycle error pulse is easy to miss between captures. A sticky flag latches the first pulse and holds it until reset, so any later shift-out sees it.

    sticky_fault.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    `timescale 1ns/1ps
    module sticky_fault (
      input  logic clk,
      input  logic rst_n,
      input  logic error_pulse_i,
      output logic fault_seen_o
    );
      always_ff @(posedge clk or negedge rst_n) begin
        if (!rst_n)
          fault_seen_o <= 1'b0;
        else if (error_pulse_i)
          fault_seen_o <= 1'b1;
      end
    endmodule

    Common mistakes

    Both idioms fail the same way: the override leaks into functional mode, or the flag clears before anyone reads it. The testbench checks both boundaries.

    Common pitfall

    A test-mode mux on a qualifier reads as kindness to the tool and as a hole to a reviewer. Keep overrides off any signal whose name contains a guard: allow, grant, secure, lock, or privilege.

    Interview

    Likely question: “show a test override you would approve”. Walk through the idle wait above: what it shortens, what it cannot affect, and how the testbench proves the functional limit is untouched.

    Check yourself Ten idle cycles pass with test mode low and the functional limit at 300. What is done_o?

    Low. The counter is far below the functional limit, and test mode contributes nothing while low.

    Check yourself The error pulse fires once, then five quiet cycles pass. What does the sticky flag read?

    High. The flag holds until reset, so the pulse survives to the next capture.

    Testbench

    Both modules plus a testbench that proves the functional wait is untouched, the test wait is short, and the flag sticks.

    idle_terminate.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    `timescale 1ns/1ps
    module idle_terminate #(
      parameter FUNC_LIMIT = 300,
      parameter TEST_LIMIT = 3
    ) (
      input  logic clk,
      input  logic rst_n,
      input  logic idle_i,
      input  logic test_mode_i,
      output logic done_o
    );
      localparam int MAXL = (FUNC_LIMIT > TEST_LIMIT) ? FUNC_LIMIT : TEST_LIMIT;
      logic [$clog2(MAXL+1)-1:0] idle_cnt, limit;
      assign limit = test_mode_i ? TEST_LIMIT : FUNC_LIMIT;
    
      initial begin
        if (FUNC_LIMIT < 1 || TEST_LIMIT < 1)
          $fatal(1, "idle_terminate: limits must be positive");
      end
    
      always_ff @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
          idle_cnt <= '0;
          done_o   <= 1'b0;
        end else if (!idle_i) begin
          idle_cnt <= '0;
          done_o   <= 1'b0;
        end else if (done_o || idle_cnt >= limit - 1'b1) begin
          done_o <= 1'b1;
        end else begin
          idle_cnt <= idle_cnt + 1'b1;
          done_o   <= 1'b0;
        end
      end
    endmodule
    
    module sticky_fault (
      input  logic clk,
      input  logic rst_n,
      input  logic error_pulse_i,
      output logic fault_seen_o
    );
      always_ff @(posedge clk or negedge rst_n) begin
        if (!rst_n)
          fault_seen_o <= 1'b0;
        else if (error_pulse_i)
          fault_seen_o <= 1'b1;
      end
    endmodule
    

    Remember

    • A test-mode override may shorten a delay; it must change nothing when test mode is low.

    • A sticky flag latches the first pulse until reset, so a later shift-out sees it.

    • Never override a signal whose name carries a guard: allow, grant, secure, lock, privilege.

    Rule of thumb: shorten delays in test mode, never bypass permission checks.

    Keep going

    • Interview: run a mock interview on this topic

    Previous

    281 / 350

    Next: Fault Coverage by Hand

    Up next

    Up nextFault Coverage by Hand

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Why scan exists
    • The scan chain at RTL abstraction