View on GitHub

COP API Reference

COP (Controllability Observability Program) - Probabilistic testability analysis using Bayesian networks for reconvergent fanout correlation modeling.

Overview

The COP module provides probability-based testability metrics:

Main Entry Point

run_cop()

Main function for COP analysis with integrated reconvergence detection.

from opentestability.core.cop import run_cop

run_cop(
    input_filename,
    output_filename,
    json_flag=False,
    reconvergence_algorithm='auto',
    reconvergence_data=None,
    auto_parallel=True,
    max_workers=4
)

Parameters:

Returns:

Example:

from opentestability.core.cop import run_cop

# Basic usage
run_cop('circuit.txt', 'cop_results.txt')

# With reconvergence and JSON output
run_cop('circuit.txt', 'cop_results.txt',
        json_flag=True,
        reconvergence_algorithm='simple')

# Large circuit with parallel processing
run_cop('large_design.txt', 'results.txt',
        reconvergence_algorithm='auto',
        auto_parallel=True,
        max_workers=8)

Controllability Module

build_controllability()

Compute C1 (probability of signal being 1) for all signals using forward propagation.

from opentestability.core.cop.controllability import build_controllability

C1 = build_controllability(nets, primary_inputs, gates, max_iterations=10000)

Parameters:

Returns:

Algorithm:

  1. Initialize primary inputs to C1 = 0.5 (random test patterns)
  2. Initialize other signals to None (uncomputed)
  3. Iteratively compute gate outputs when inputs are ready
  4. Continue until convergence or max iterations reached

Example:

nets = ['a', 'b', 'n1', 'z']
inputs = ['a', 'b']
gates = [
    ('AND2X1', 'n1', ['a', 'b']),
    ('INVX1', 'z', ['n1'])
]

C1 = build_controllability(nets, inputs, gates)
print(f"Signal z has C1 = {C1['z']:.4f}")

get_controllability_metrics()

Package controllability metrics for output.

from opentestability.core.cop.controllability import get_controllability_metrics

metrics = get_controllability_metrics(C1)

Returns:

{
    'signal_name': {
        'c1': 0.5,  # Probability signal is 1
        'c0': 0.5   # Probability signal is 0
    }
}

Gate Logic Module

Probabilistic transfer functions for various gate types.

calculate_gate_c1()

Main dispatcher for calculating C1 of any gate type.

from opentestability.core.cop.gate_logic import calculate_gate_c1

output_c1 = calculate_gate_c1(gate_type, input_c1_list)

Parameters:

Returns:

Supported Gates:

Example:

# 2-input AND gate with inputs at 0.5 probability
c1_out = calculate_gate_c1('AND2X1', [0.5, 0.5])
# Result: 0.25 (0.5 × 0.5)

Individual Gate Functions

calculate_inv_c1()

Inverter: out.C1 = 1.0 - in.C1

c1_out = calculate_inv_c1(input_c1)

calculate_and_c1()

AND gate: out.C1 = ∏(input.C1)

c1_out = calculate_and_c1([0.5, 0.5, 0.5])
# Result: 0.125

calculate_or_c1()

OR gate: out.C1 = 1.0 - ∏(1.0 - input.C1)

c1_out = calculate_or_c1([0.5, 0.5])
# Result: 0.75

calculate_xor_c1()

XOR gate: out.C1 = (a.C1 × (1-b.C1)) + ((1-a.C1) × b.C1)

c1_out = calculate_xor_c1([0.5, 0.5])
# Result: 0.5

Observability Module

build_observability()

Compute observability for all signals using backward propagation.

from opentestability.core.cop.observability import build_observability

Obs = build_observability(
    nets,
    primary_outputs,
    gates,
    C1,
    reconvergent_sites=None,
    max_iterations=10000
)

Parameters:

Returns:

Algorithm:

  1. Initialize primary outputs to Obs = 1.0 (fully observable)
  2. Initialize other signals to 0.0
  3. Iterate backward through gates, computing input observabilities
  4. For fanouts, combine branches using union formula (if independent)
  5. Mark reconvergent sites for Bayesian processing

Example:

Obs = build_observability(nets, outputs, gates, C1)
print(f"Signal 'a' observability: {Obs['a']:.4f}")

calculate_branch_observability()

Calculate observability of a signal through a specific gate branch.

from opentestability.core.cop.observability import calculate_branch_observability

branch_obs = calculate_branch_observability(
    signal, gate_type, gate_output, gate_inputs, output_obs, C1
)

Logic by Gate Type:

combine_fanout_observabilities()

Combine observabilities from multiple fanout branches.

from opentestability.core.cop.observability import combine_fanout_observabilities

combined_obs = combine_fanout_observabilities(branch_obs_list)

Formula: For independent branches: Obs = 1 - ∏(1 - Obs_branch)

This represents probability that signal is observable through at least one branch.


Reconvergence Module

Bayesian network-based reconvergence handling with correlation modeling.

extract_reconvergent_sites()

Extract set of reconvergent site signals from reconvergence data.

from opentestability.core.cop.reconvergence import extract_reconvergent_sites

sites = extract_reconvergent_sites(reconvergence_data)

Returns:

adjust_cop_for_reconvergence()

Adjust COP observability values for reconvergent sites using Bayesian correlation.

from opentestability.core.cop.reconvergence import adjust_cop_for_reconvergence

adjusted_obs = adjust_cop_for_reconvergence(Obs, C1, reconvergence_data, gates)

Parameters:

Returns:

How It Works:

  1. Identifies reconvergent fanouts from data
  2. Builds Bayesian network for reconvergent paths
  3. Calculates correlation coefficients
  4. Applies correlation-based adjustments instead of independence assumption

BayesianNetwork Class

Simplified Bayesian network for modeling signal dependencies.

from opentestability.core.cop.reconvergence import BayesianNetwork

bn = BayesianNetwork()
bn.build_from_paths(path1, path2)
correlation = bn.calculate_correlation(path1, path2)

Methods:

add_dependency()

bn.add_dependency(parent_signal, child_signal)

build_from_paths()

bn.build_from_paths(path1, path2)

calculate_correlation()

correlation = bn.calculate_correlation(path1, path2)

Returns correlation coefficient in [0, 1] based on shared ancestor signals.

calculate_correlated_observability()

Calculate observability for reconvergent site using correlation.

from opentestability.core.cop.reconvergence import calculate_correlated_observability

adjusted_obs = calculate_correlated_observability(site, branch_obs_list, correlation)

Formula:


Parallel Module

Parallel computation support for large circuits (>100,000 gates).

build_cop_with_parallel()

Build complete COP analysis with parallel computation.

from opentestability.core.cop.parallel import build_cop_with_parallel

C1, Obs = build_cop_with_parallel(
    nets, inputs, outputs, gates,
    reconvergent_sites, reconvergence_data,
    max_workers=4
)

Parameters:

Returns:

Performance:


Output Module

Output formatting for COP results.

write_cop()

Write COP results to text file.

from opentestability.core.cop.output import write_cop

write_cop(C1, Obs, filename)

Output Format:

============================================================
COP (Controllability Observability Program) Analysis
============================================================

--- CONTROLLABILITY PROBABILITIES (C1) ---
C1 = Probability that signal is 1
C0 = 1 - C1 (Probability that signal is 0)

signal_a              C1: 0.500000  C0: 0.500000
signal_b              C1: 0.500000  C0: 0.500000
...

--- OBSERVABILITY PROBABILITIES (Obs) ---
Obs = Probability that signal fault is observable at outputs

signal_a              Obs: 0.750000
signal_b              Obs: 0.750000
...

--- TESTABILITY METRICS ---
Testability = C1 * Obs (probability of setting and observing)

signal_a              Testability: 0.375000
signal_b              Testability: 0.375000
...

dump_json()

Write COP results to JSON file.

from opentestability.core.cop.output import dump_json

dump_json(C1, Obs, inputs, outputs, gates, filename)

JSON Schema:

{
  "analysis_type": "COP",
  "description": "Controllability Observability Program Analysis",
  "primary_inputs": ["a", "b"],
  "primary_outputs": ["z"],
  "metrics": [
    {
      "gate": "AND2X1_0",
      "output": "n1",
      "inputs": ["a", "b"],
      "c1": 0.25,
      "c0": 0.75,
      "obs": 1.0,
      "testability": 0.25
    }
  ]
}

format_cop_summary()

Generate summary of COP results for display.

from opentestability.core.cop.output import format_cop_summary

summary = format_cop_summary(C1, Obs, primary_inputs, primary_outputs)
print(summary)

Output:

============================================================
COP Analysis Summary
============================================================

Primary Inputs (2):
  a                     C1: 0.5000
  b                     C1: 0.5000

Primary Outputs (1):
  z                     Obs: 1.0000  Testability: 0.7500

Average C1: 0.5625
Average Observability: 0.8750

Testability Statistics:
  Average: 0.4531
  Minimum: 0.1250
  Maximum: 0.7500
============================================================

Complete Example

from opentestability.core.cop import run_cop
from opentestability.core.cop.controllability import build_controllability
from opentestability.core.cop.observability import build_observability
from opentestability.core.cop.reconvergence import (
    extract_reconvergent_sites,
    adjust_cop_for_reconvergence
)
from opentestability.core.cop.output import write_cop, dump_json

# Method 1: Simple high-level API
run_cop('circuit.txt', 'cop_results.txt',
        json_flag=True,
        reconvergence_algorithm='auto',
        auto_parallel=True)

# Method 2: Manual step-by-step
# (Assuming you have nets, inputs, outputs, gates from netlist parser)

# Step 1: Compute controllability
C1 = build_controllability(nets, inputs, gates)

# Step 2: Compute observability
Obs = build_observability(nets, outputs, gates, C1)

# Step 3: Apply reconvergence adjustments (if data available)
if reconvergence_data:
    reconv_sites = extract_reconvergent_sites(reconvergence_data)
    Obs = adjust_cop_for_reconvergence(Obs, C1, reconvergence_data, gates)

# Step 4: Write outputs
write_cop(C1, Obs, 'results.txt')
dump_json(C1, Obs, inputs, outputs, gates, 'results.json')

Performance Considerations

Circuit Size Thresholds

Circuit Size Processing Mode Expected Time
< 1,000 gates Sequential < 1 second
1,000 - 100,000 gates Sequential 1-10 seconds
> 100,000 gates Automatic Parallel 3-4x faster

Memory Usage

Optimization Tips

  1. Use auto_parallel=True for large circuits (default behavior)
  2. Adjust max_workers based on available CPU cores
  3. Use simple reconvergence algorithm for best speed/accuracy tradeoff
  4. Enable JSON output only when needed (saves I/O time)

Additional Resources