TMR Strategies

TMRX supports two complementary TMR strategies that can be mixed within the same design hierarchy.

Logic TMR

Logic TMR triplicates the internal logic of a module while optionally preserving the original interface.

What Gets Triplicated

  • All combinational logic gates

  • All wires and signals

  • All flip-flops

  • All internal connections

How It Works

  1. Every wire and cell is duplicated with configurable suffixes (for example, _a, _b, _c).

  2. Majority voters are inserted after flip-flop outputs (configurable).

  3. If preserve_module_ports = true, voters are inserted at outputs to maintain the original interface.

  4. If preserve_module_ports = false, the module interface is expanded with triplicated ports.

Full Module TMR

Full Module TMR creates a wrapper module containing three independent instances of the original module.

What Gets Created

  • A new wrapper module with the original module name

  • The original module renamed with a _tmrx_worker suffix

  • Three instances of the worker module inside the wrapper

  • Optional input voters (before modules)

  • Optional output voters (after modules)

How It Works

  1. The original module is renamed and wrapped.

  2. Three instances are created with connections to wrapper ports.

  3. If preserve_module_ports = false, ports are triplicated.

  4. Voters can be inserted at inputs, outputs, or both.

Choosing a Strategy

Consideration Logic TMR Full Module TMR

Interface changes

Optional (with preserve_module_ports)

Optional (with preserve_module_ports)

Voter placement

After FFs, at outputs

At module boundaries

Area overhead

Generally lower

Slightly higher (wrapper overhead)

Black-box modules

Not applicable

Required

Black-box modules (modules with the blackbox attribute, memories, or processes) are automatically assigned Full Module TMR because their internals cannot be modified.

Child Module Version Selection

When a design mixes TMR strategies, a parent module may instantiate a child that has been processed by TMRX. Which version of the child a parent sees depends on the child’s preserve_module_ports setting.

Child with preserve_module_ports = false

When a child module is expanded with preserve_module_ports = false, TMRX keeps two versions of it in the design:

  • The original module with its unchanged interface.

  • A _tmrx_impl clone with triplicated ports and TMR’d internals.

Which version a parent uses depends on the parent’s TMR mode:

Parent TMR mode Child version used

LogicTMR

_tmrx_impl — the TMR’d clone with triplicated ports. TMRX automatically remaps cell references during Logic TMR expansion.

FullModuleTMR

Original — the non-expanded module with its original interface. Each of the three worker copies instantiates the original child.

None

Original — the non-expanded module with its original interface. The parent is not processed by TMRX, so no remapping occurs.

This means a child module that is TMR’d with preserve_module_ports = false is not redundant inside a FullModuleTMR or None parent. The three FullModuleTMR workers each hold one copy of the original child, and a None parent holds one copy as well.

Child with preserve_module_ports = true

When a child module is expanded with preserve_module_ports = true, there is only one version of the module. TMRX expands it in-place: the interface is unchanged, but the internals are now triplicated.

All parent modes — LogicTMR, FullModuleTMR, and None — instantiate this single module. Every parent therefore gets the TMR’d internals regardless of its own TMR mode.

Summary

Child preserve_module_ports Parent mode Child internals TMR’d?

false

LogicTMR

Yes — _tmrx_impl clone used

false

FullModuleTMR

No — original module used

false

None

No — original module used

true

Any

Yes — single in-place expanded module used

If you want a TMR’d child module to be redundant inside a FullModuleTMR or None parent, set preserve_module_ports = true on the child. Without it, the child’s TMR expansion is invisible to those parent modes.