A flip-flop needs D stable for t_su before the clock edge and t_h after it. A change inside that window can leave the output between 0 and 1 for an unbounded time.
Long delays are exponentially unlikely. When the output resolves, it takes the old or the new value, effectively at random.
How to read it: time runs left to right, the shaded band is the setup and hold window around the capture edge, and each row shows data D above the flip-flop output Q.
Rows 1 and 3 are safe. D is either stable before t_su or changes after t_h, so Q is the old or the new value, cleanly.
Row 2 is the failure. Q may sit between 0 and 1 and later settle to either rail, and which one is effectively random.
t_r is the time Q has to settle before the next stage samples it. A synchroniser exists to make t_r long enough, as the next section explains.
Mean time between failures grows exponentially with resolution time. A synchroniser gives the first flop a full clock period to settle.
Term | Meaning |
|---|---|
t_r | Resolution time: how long the flop output has to settle before the next stage samples it |
τ | Time constant of the flop's regenerative feedback (technology dependent, tens of picoseconds) |
T_W | Width of the vulnerable window (also technology dependent) |
f_clk, f_data | Clock frequency of the sampling flop and rate of data changes |
The exponential in the numerator dominates. Each extra picosecond of settling multiplies MTBF.
The historical name meta_ff below denotes a sampling-uncertainty model, not an analogue metastability model. A setup/hold-window hit selects a random digital 0 or 1 after fixed TCQ. It illustrates uncertain capture; it has no late-resolution distribution, analogue voltage, or divergent downstream interpretation. The full listing sits under Testbench below.
The counter meta_events counts model window hits, not metastability failures. An actual failure depends on resolution remaining unsafe at downstream sampling. A clean digital output or zero model errors cannot measure MTBF or prove those failures absent. Reliability needs library-characterised parameters, implemented interstage slack, activity assumptions, and physical signoff; none is supplied by this bench.
With fixed overhead h, t_r changes from T - h to T/2 - h. At fixed source transition rate f_data, MTBF_new/MTBF_old = exp(-T/(2τ))/2. Only if source activity also doubles (for example f_data = f_clk/10) does the denominator contribute /4 instead. State the activity assumption and use actual implementation slack.
`timescale 1ns/1ps
// Sampling uncertainty only: random digital capture at fixed TCQ after a window hit.
// No analogue state, late-resolution tail, or downstream disagreement is modelled.
module meta_ff #(parameter real TCQ = 0.3, TSU = 0.15, THD = 0.1) (
input logic clk, d,
output logic q
);
realtime t_d = -100.0, t_clk = -100.0;
int meta_events = 0;
initial q = 1'b0;
always @(d) begin
t_d = $realtime;
if ($realtime - t_clk < THD) begin // changed just after the edge (hold window)
meta_events++; q <= #TCQ $urandom_range(0, 1);
end
end
always @(posedge clk) begin
t_clk = $realtime;
if ($realtime - t_d < TSU) begin // changed just before the edge (setup window)
meta_events++; q <= #TCQ $urandom_range(0, 1);
end else q <= #TCQ d;
end
endmodule
Outside the window the model flop is exact. Inside it, the model picks the old or the new value at random: in one run, 230 of 400 captures took the new value and 170 the old.
Sampling-uncertainty source checker, run with Icarus Verilog 13.0 (2026-10-16): prints PASS. It checks exact capture outside the model window and random outcomes inside it. It is not a physical reliability experiment.
Model run (Icarus Verilog 13.0, 2026-10-16): 230 new-value and 170 old-value captures out of 400. This shows the digital random choice only; it is not a measured physical failure rate.