Redundancy — TMR (triple modular redundancy), voting logic
Overview
Triple Modular Redundancy (TMR) is a fault-tolerance technique where three identical modules execute the same computation in parallel, and a voter selects the majority output. This masks single-point failures in safety-critical systems like aerospace, medical devices, and autonomous vehicles.
Why TMR matters: A single bit-flip from cosmic radiation or hardware aging can crash a spacecraft computer. TMR ensures that one faulty module cannot compromise the system output.
[!intuition] The Core Idea
Imagine three clocks showing time. If one breaks and shows the wrong time, you can still trust the other two that agree. TMR does the same with computations:
- Redundancy: Run the same task on 3 independent hardware/software modules
- Voting: Compare outputs; the majority (2-out-of-3) wins
- Masking: Hide the faulty module's error from the system
Key insight: TMR trades space (3× hardware) and power (3× computation) for reliability (masks 1 fault). It cannot detect which module failed, only that one disagrees.
[!definition] Formal Definition
A TMR system consists of:
- Three identical modules computing function
- A voter that applies a majority function: where is module 's output
Assumptions:
- Modules fail independently (no common-cause failure)
- Voter is ultra-reliable (often hardened or redundant itself)
- Failures are fail-silent (a faulty component stops producing output or signals an error rather than emitting wrong data; contrast with a fail-incorrect module that keeps outputting plausible but wrong values, which is harder for a voter to handle)
[!formula] Reliability Derivation
Setup: Each module has reliability (probability of correct operation over time ). Assume exponential failure: where is failure rate.
Single Module System
Why? Only one module; if it fails, system fails. is —there is no extra factor.
TMR System
The system works if at least 2 of 3 modules work (voter picks majority).
Step 1: Probability all 3 work:
Why? Independent failures multiply: .
Step 2: Probability exactly 2 work (one fails):
- Choose which 2 work: ways
- Each scenario: (two work, one fails)
Why this step? Binomial probability: pick 2 successes from 3 trials.
Step 3: Total TMR reliability:
Simplify:
Interpretation:
- If : Single module , TMR ✅ Better!
- If : TMR is worse than single module (unreliable modules outvote the good one)
Critical threshold: TMR only helps if (modules are more reliable than not).
[!example] Example 1: Sensor Reading Voter
Scenario: Three temperature sensors reading a furnace. Outputs: 850°C, 850°C, 920°C.
Voter logic (software):
def majority_vote(vals):
"""Returns majority value if 2+ agree, else None"""
if vals[0] == vals[1] or vals[0] == vals[2]:
return vals[0]
elif vals[1] == vals[2]:
return vals[1]
else:
return None # All disagree - catastrophic failure
sensors = [850, 850, 920]
output = majority_vote(sensors) # Returns 850Why this step?
- Compare pair-wise: if any two agree, that's the majority
- If all three disagree, TMR cannot decide (requires higher redundancy like 5-modular)
Real-world: The 920°C sensor likely has a bias fault (calibration drift). The voter masks it; system proceeds with 850°C.
[!example] Example 2: Critical Computation in Flight Control
Scenario: Compute aileron deflection angle .
Modules:
- Module 1:
- Module 2:
- Module 3: (hardware glitch flipped sign bit)
Voter (hardware comparator):
- Checks bit-by-bit equality
- → Output
Why this step? Hardware voters use bit-level comparison (faster than floating-point equality). If any two outputs match exactly, send that value to actuators.
Consequence: Aircraft maintains stable roll; the faulty module is masked. Ground diagnostics later identify Module 3 for replacement.
[!example] Example 3: Voter Failure Modes
Scenario: All three modules output different values: 100, 105, 110 (within sensor noise).
Problem: Strict equality voting fails. Need approximate voting:
def approximate_vote(vals, tolerance=5):
"""Majority within tolerance"""
for i in range(len(vals)):
matches = sum(1 for v in vals if abs(v - vals[i]) <= tolerance)
if matches >= 2:
return vals[i]
return None # No consensus
sensors = [100, 105, 110]
output = approximate_vote(sensors, tolerance=10) # Returns 100 (first in majority)Why this step? Analog sensors have noise. Exact matching is too strict; we vote on "close enough" values using a tolerance window.
Trade-off: Tolerance too large → mask real faults. Tolerance too small → false disagreements.
[!mistake] Common Mistakes
Mistake 1: "TMR always improves reliability"
Why it feels right: More redundancy = more safety, right?
Why it's wrong: If module reliability (more likely to fail than work), TMR is worse than a single module.
The math:
- Single:
- TMR: ❌ Worse!
Why? Two unreliable modules outvote the one good module more often than all three work.
Fix: Only use TMR when . For unreliable components, fix the base reliability first (better hardware, screening) before adding redundancy.
Mistake 2: "The voter is just an OR gate"
Why it feels right: OR gates are simple; if any module works, output is good.
Why it's wrong: OR would pass through a faulty output. We need majority, not any:
| OR | Majority | |||
|---|---|---|---|---|
| 0 | 1 | 0 | 1 | 0 |
| 1 | 0 | 0 | 1 | 0 |
| 1 | 1 | 0 | 1 | 1 ✅ |
Why this step? OR gate outputs 1 if any input is 1 (useless for fault tolerance). Majority outputs 1 only if most inputs are 1 (2 or more).
Fix: Use a majority gate (2-out-of-3 logic): .
Mistake 3: "TMR detects which module failed"
Why it feels right: Three modules vote; we know two agreed, so the third must be faulty.
Why it's wrong: TMR only masks faults, it doesn't diagnose them. You know someone is wrong, but not who (unless you add comparison logic).
Example:
- Outputs: 50, 50, 75
- Voter: picks 50 (majority)
- Question: Is Module 3 broken, or are Modules 1 & 2 both broken identically (common-cause)?
Fix: Add self-checking pairs or watchdog timers to identify faulty modules for maintenance. TMR + diagnostics = robust system.
[!formula] Voter Logic Design
Boolean Majority Function (Digital)
For binary outputs :
Derivation:
- Output is 1 if at least two inputs are 1
- Truth table approach:
- : Always 1 →
- : Always 1 →
- : Always 1 →
- OR these terms together (if any pair is true, output is true)
Why this step? Each product term represents one pair agreeing. OR-ing them captures "any two agree".
Hardware: Implement with 3 AND gates + 1 OR gate. Propagation delay: 2 gate delays.
Analog Voter (Median Filter)
For continuous outputs :
Why median, not average?
- Average: → faulty outlier skews result
- Median: → outlier ignored ✅
Algorithm:
- Sort values:
- Pick middle:
Hardware: Use analog comparator circuits to find min/max, then compute median = .
[!example] Example 4: Real-Time Voter Timing
Scenario: Flight control running at 100 Hz (10 ms period). TMR modules must complete + vote within deadline.
Timing breakdown:
- Module computation: 3 ms each (parallel)
- Voter comparison: 0.5 ms
- Total: ms ✅ (within 10 ms)
Why this step? Parallel execution means we wait for the slowest module, not the sum. Voter adds serial delay.
Failure case: If one module hangs (infinite loop), we need a timeout:
import multiprocessing
def compute_with_timeout(func, args, timeout_ms):
# Shared queue lets the child return its actual result
q = multiprocessing.Queue()
def worker(q, args):
q.put(func(*args))
p = multiprocessing.Process(target=worker, args=(q, args))
p.start()
p.join(timeout_ms / 1000.0)
if p.is_alive():
p.terminate() # Kill the hung module
p.join()
return None # Fail-silent: no output within deadline
return q.get() # Retrieve the module's real computed resultWhy? If a module doesn't respond in time, treat it as failed (returns None). The result must be pulled back from the child process via a shared Queue—a plain function call in another process cannot return a value directly. The voter then uses the other two outputs.
[!mnemonic] TMR Memory Hook
"Two Trusty, reject the Rogue"
- Two modules agree? Trust them.
- Reject the Rogue outlier.
Visual: Picture three guards voting on "friend or foe". Two say "friend" → majority wins, even if third guard is confused.
[!recall]- Feynman Explanation (ELI12)
Imagine you're doing a math test, and you're not sure if you got the right answer. So you ask three friends to solve the same problem. If two friends get the same answer, you trust that one. If one friend got something totally different, maybe they made a mistake—but you're safe because the other two agree!
That's how computers stay safe in rockets or hospital machines. They run the same calculation three times on three different "mini-computers." If one mini-computer breaks (maybe a tiny wire got zapped by space radiation!), the other two still work and tell the correct answer. The "voter" is like a referee who picks the answer that two computers agree on.
Why three, not two? With two computers, if they disagree, you don't know who's right! With three, the majority (two) is almost always correct—unless you're really unlucky and two break at the exact same time (very rare if they're independent).
Connections
- Fault Tolerance Fundamentals — TMR is one pattern; compare to N-version programming
- Watchdog Timers — Detect hung modules that don't output in time
- Error Detection Codes — Hamming/CRC detect errors; TMR corrects them
- Safety-Critical Systems Standards — DO-178C, IEC 61508 mandate redundancy for certain SIL levels
- Common-Cause Failures — TMR assumes independence; diverse implementations reduce common-mode risk
- Byzantine Fault Tolerance — When modules can lie maliciously (not just fail-silent); requires 4+ modules
- Redundancy vs. Diversity — TMR uses identical modules; N-version uses different algorithms/languages
Key Takeaways
- TMR masks single faults by voting on three parallel computations (2-out-of-3 majority)
- Reliability improves only if (module reliability threshold)
- Voter must be ultra-reliable (often the weakest link; use hardened hardware or voter redundancy)
- TMR doesn't diagnose which module failed—only masks it; add self-checking for maintenance
- Analog systems need median voting (average is vulnerable to outliers)
- Real-time systems must budget voter delay and handle timeouts (fail-silent assumption)
#flashcards/coding
What is Triple Modular Redundancy (TMR)?
Why does TMR require R > 0.5 for reliability improvement?
What is the boolean logic for a TMR voter with binary inputs ?
Why use median instead of average for analog TMR voting?
What is the key assumption for TMR to work?
What does "fail-silent" mean vs "fail-incorrect"?
Can TMR detect which module failed?
What happens if all three TMR modules output different values?
How does TMR affect real-time system timing?
Concept Map
Hinglish (regional understanding)
Intuition Hinglish mein samjho
Hinglish (regional understanding)
Intuition Hinglish mein samjho
Dekho yaar, TMR ka core idea bilkul simple hai — imagine tumhare paas teen ghadiyan hain jo time dikha rahi hain. Agar ek ghadi kharab ho jaaye aur galat time dikhaye, toh bhi tum baaki do par bharosa kar sakte ho jo aapas mein agree kar rahi hain. Bas yehi cheez TMR karta hai computations ke saath — teen identical modules ek hi kaam parallel mein karte hain, aur ek "voter" majority output (2-out-of-3) choose kar leta hai. Iska matlab, agar ek module mein fault aa bhi gaya — jaise cosmic radiation se bit-flip ya hardware aging — toh woh faulty module poore system ko crash nahi kar sakta, kyunki baaki do usse outvote kar dete hain.
Ab why-it-matters wali baat samjho. Safety-critical systems mein — jaise spacecraft, medical devices, ya autonomous vehicles — ek chhoti si galti bhi disaster ban sakti hai. Yahan TMR ek trade-off deta hai: tum 3x hardware aur 3x power kharch karte ho, lekin badle mein reliability milti hai jo ek single fault ko completely mask kar deti hai. Formula bhi yaad rakhna — . Agar single module ki reliability hai, toh TMR se 0.972 ho jaati hai, kaafi better! Lekin ek critical catch hai: TMR sirf tabhi help karta hai jab ho. Agar modules already zyada unreliable hain, toh do kharab module mil ke ek acche wale ko outvote kar denge, aur system aur bura ho jayega.
Ek important nuance yeh bhi hai ki TMR yeh nahi bata sakta ki kaunsa module fail hua — bas itna pata chalta hai ki koi ek disagree kar raha hai. Aur yeh best tab kaam karta hai jab failures "fail-silent" hon, matlab kharab component chup ho jaaye ya error signal de, bajaye galat-magar-plausible values dene ke. Isliye jab tum embedded ya real-time systems padho, toh yaad rakhna — redundancy sirf hardware duplicate karna nahi hai, balki voting logic aur reliability assumptions ko samajhna asli game hai.