FAILURE MAP
← Case archive

FA-89081 / Digital logic simulation / Open access

Falling edges into unknown are missed · case 01

1->x and 1->z transitions are not reported as negedges.

Verified by executionVariant 1 · 7 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

Negedge detection only looks for a destination of 0.

VERIFIED REPAIR

Classify every move to a lower level as a negedge.

Unsuccessful approach: Requiring the source to be 1 still misses x->0 and z->0.

Case contract

Input [seq]: a string of samples over '0','1','x','z'. Levels order 0 < {x,z} < 1 (x and z are the same middle level). A change to a higher level is a posedge (0->1, 0->x, 0->z, x->1, z->1), to a lower level a negedge; x<->z is no edge. The first sample has no predecessor. Return [posedge indices, negedge indices].

Why this case matters

Event controls on clocks and resets fire on unknown transitions; an edge classifier that only knows 0->1 misses or invents triggers.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    seq = args[0]
    lvl = {'0': 0, '1': 2}
    pos, neg = [], []
    prev = None
    for i, b in enumerate(seq):
        a, prev = prev, b
        if a is None or a == b:
            continue
        la, lb = lvl.get(a, 1), lvl.get(b, 1)
        if la < lb:
            pos.append(i)
        elif b == '0':
            neg.append(i)
    return [pos, neg]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('plain binary toggles', ['010110'], [[1, 3], [2, 5]]), ('edges through unknown and floating', ['0x1z0'], [[1, 2], [3, 4]]), ('unknown to floating is no edge', ['xzx1z'], [[3], [4]]), ('floating rising and falling', ['z1z0z'], [[1, 4], [2, 3]]), ('high to floating then low', ['1xz0'], [[], [1, 3]]), ('starts high without a predecessor', ['110'], [[], [2]]), ('low through unknown to high', ['0x1x0'], [[1, 2], [3, 4]])], [('plain binary toggles', ['0101110'], [[1, 3], [2, 6]]), ('edges through unknown and floating', ['0x1z0'], [[1, 2], [3, 4]]), ('unknown to floating is no edge', ['xxzx1z'], [[4], [5]]), ('floating rising and falling', ['z1z0zz'], [[1, 4], [2, 3]]), ('high to floating then low', ['1xxz0'], [[], [1, 4]]), ('starts high without a predecessor', ['1100'], [[], [2]]), ('low through unknown to high', ['00x1x0'], [[2, 3], [4, 5]])], [('plain binary toggles', ['01011110'], [[1, 3], [2, 7]]), ('edges through unknown and floating', ['0x1z0'], [[1, 2], [3, 4]]), ('unknown to floating is no edge', ['xxxzx1z'], [[5], [6]]), ('floating rising and falling', ['z1z0zzz'], [[1, 4], [2, 3]]), ('high to floating then low', ['1xxxz0'], [[], [1, 5]]), ('starts high without a predecessor', ['11000'], [[], [2]]), ('low through unknown to high', ['000x1x0'], [[3, 4], [5, 6]])], [('plain binary toggles', ['010111110'], [[1, 3], [2, 8]]), ('edges through unknown and floating', ['0x1z0'], [[1, 2], [3, 4]]), ('unknown to floating is no edge', ['xxxxzx1z'], [[6], [7]]), ('floating rising and falling', ['z1z0zzzz'], [[1, 4], [2, 3]]), ('high to floating then low', ['1xxxxz0'], [[], [1, 6]]), ('starts high without a predecessor', ['110000'], [[], [2]]), ('low through unknown to high', ['0000x1x0'], [[4, 5], [6, 7]])], [('plain binary toggles', ['0101111110'], [[1, 3], [2, 9]]), ('edges through unknown and floating', ['0x1z0'], [[1, 2], [3, 4]]), ('unknown to floating is no edge', ['xxxxxzx1z'], [[7], [8]]), ('floating rising and falling', ['z1z0zzzzz'], [[1, 4], [2, 3]]), ('high to floating then low', ['1xxxxxz0'], [[], [1, 7]]), ('starts high without a predecessor', ['1100000'], [[], [2]]), ('low through unknown to high', ['00000x1x0'], [[5, 6], [7, 8]])]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
plain binary toggles[[1, 3], [2, 5]][[1, 3], [2, 5]]Passed
edges through unknown and floating[[1, 2], [4]][[1, 2], [3, 4]]Failed
unknown to floating is no edge[[3], []][[3], [4]]Failed
floating rising and falling[[1, 4], [3]][[1, 4], [2, 3]]Failed
high to floating then low[[], [3]][[], [1, 3]]Failed
starts high without a predecessor[[], [2]][[], [2]]Passed
low through unknown to high[[1, 2], [4]][[1, 2], [3, 4]]Failed

SHA-256 / 7fd6402a5471d7cd43e097d95d26b01700a46470b5603759506478ef07295b6a

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    seq = args[0]
    lvl = {'0': 0, '1': 2}
    pos, neg = [], []
    prev = None
    for i, b in enumerate(seq):
        a, prev = prev, b
        if a is None or a == b:
            continue
        la, lb = lvl.get(a, 1), lvl.get(b, 1)
        if la < lb:
            pos.append(i)
        elif a == '1':
            neg.append(i)
    return [pos, neg]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('plain binary toggles', ['010110'], [[1, 3], [2, 5]]), ('edges through unknown and floating', ['0x1z0'], [[1, 2], [3, 4]]), ('unknown to floating is no edge', ['xzx1z'], [[3], [4]]), ('floating rising and falling', ['z1z0z'], [[1, 4], [2, 3]]), ('high to floating then low', ['1xz0'], [[], [1, 3]]), ('starts high without a predecessor', ['110'], [[], [2]]), ('low through unknown to high', ['0x1x0'], [[1, 2], [3, 4]])], [('plain binary toggles', ['0101110'], [[1, 3], [2, 6]]), ('edges through unknown and floating', ['0x1z0'], [[1, 2], [3, 4]]), ('unknown to floating is no edge', ['xxzx1z'], [[4], [5]]), ('floating rising and falling', ['z1z0zz'], [[1, 4], [2, 3]]), ('high to floating then low', ['1xxz0'], [[], [1, 4]]), ('starts high without a predecessor', ['1100'], [[], [2]]), ('low through unknown to high', ['00x1x0'], [[2, 3], [4, 5]])], [('plain binary toggles', ['01011110'], [[1, 3], [2, 7]]), ('edges through unknown and floating', ['0x1z0'], [[1, 2], [3, 4]]), ('unknown to floating is no edge', ['xxxzx1z'], [[5], [6]]), ('floating rising and falling', ['z1z0zzz'], [[1, 4], [2, 3]]), ('high to floating then low', ['1xxxz0'], [[], [1, 5]]), ('starts high without a predecessor', ['11000'], [[], [2]]), ('low through unknown to high', ['000x1x0'], [[3, 4], [5, 6]])], [('plain binary toggles', ['010111110'], [[1, 3], [2, 8]]), ('edges through unknown and floating', ['0x1z0'], [[1, 2], [3, 4]]), ('unknown to floating is no edge', ['xxxxzx1z'], [[6], [7]]), ('floating rising and falling', ['z1z0zzzz'], [[1, 4], [2, 3]]), ('high to floating then low', ['1xxxxz0'], [[], [1, 6]]), ('starts high without a predecessor', ['110000'], [[], [2]]), ('low through unknown to high', ['0000x1x0'], [[4, 5], [6, 7]])], [('plain binary toggles', ['0101111110'], [[1, 3], [2, 9]]), ('edges through unknown and floating', ['0x1z0'], [[1, 2], [3, 4]]), ('unknown to floating is no edge', ['xxxxxzx1z'], [[7], [8]]), ('floating rising and falling', ['z1z0zzzzz'], [[1, 4], [2, 3]]), ('high to floating then low', ['1xxxxxz0'], [[], [1, 7]]), ('starts high without a predecessor', ['1100000'], [[], [2]]), ('low through unknown to high', ['00000x1x0'], [[5, 6], [7, 8]])]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
plain binary toggles[[1, 3], [2, 5]][[1, 3], [2, 5]]Passed
edges through unknown and floating[[1, 2], [3]][[1, 2], [3, 4]]Failed
unknown to floating is no edge[[3], [4]][[3], [4]]Passed
floating rising and falling[[1, 4], [2]][[1, 4], [2, 3]]Failed
high to floating then low[[], [1]][[], [1, 3]]Failed
starts high without a predecessor[[], [2]][[], [2]]Passed
low through unknown to high[[1, 2], [3]][[1, 2], [3, 4]]Failed

SHA-256 / 9ab9685dfc89a265f2e3fde76fb9181b03a8113d15abe8c1f487b5ac3049b5c7

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    seq = args[0]
    lvl = {'0': 0, '1': 2}
    pos, neg = [], []
    prev = None
    for i, b in enumerate(seq):
        a, prev = prev, b
        if a is None or a == b:
            continue
        la, lb = lvl.get(a, 1), lvl.get(b, 1)
        if la < lb:
            pos.append(i)
        elif la > lb:
            neg.append(i)
    return [pos, neg]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('plain binary toggles', ['010110'], [[1, 3], [2, 5]]), ('edges through unknown and floating', ['0x1z0'], [[1, 2], [3, 4]]), ('unknown to floating is no edge', ['xzx1z'], [[3], [4]]), ('floating rising and falling', ['z1z0z'], [[1, 4], [2, 3]]), ('high to floating then low', ['1xz0'], [[], [1, 3]]), ('starts high without a predecessor', ['110'], [[], [2]]), ('low through unknown to high', ['0x1x0'], [[1, 2], [3, 4]])], [('plain binary toggles', ['0101110'], [[1, 3], [2, 6]]), ('edges through unknown and floating', ['0x1z0'], [[1, 2], [3, 4]]), ('unknown to floating is no edge', ['xxzx1z'], [[4], [5]]), ('floating rising and falling', ['z1z0zz'], [[1, 4], [2, 3]]), ('high to floating then low', ['1xxz0'], [[], [1, 4]]), ('starts high without a predecessor', ['1100'], [[], [2]]), ('low through unknown to high', ['00x1x0'], [[2, 3], [4, 5]])], [('plain binary toggles', ['01011110'], [[1, 3], [2, 7]]), ('edges through unknown and floating', ['0x1z0'], [[1, 2], [3, 4]]), ('unknown to floating is no edge', ['xxxzx1z'], [[5], [6]]), ('floating rising and falling', ['z1z0zzz'], [[1, 4], [2, 3]]), ('high to floating then low', ['1xxxz0'], [[], [1, 5]]), ('starts high without a predecessor', ['11000'], [[], [2]]), ('low through unknown to high', ['000x1x0'], [[3, 4], [5, 6]])], [('plain binary toggles', ['010111110'], [[1, 3], [2, 8]]), ('edges through unknown and floating', ['0x1z0'], [[1, 2], [3, 4]]), ('unknown to floating is no edge', ['xxxxzx1z'], [[6], [7]]), ('floating rising and falling', ['z1z0zzzz'], [[1, 4], [2, 3]]), ('high to floating then low', ['1xxxxz0'], [[], [1, 6]]), ('starts high without a predecessor', ['110000'], [[], [2]]), ('low through unknown to high', ['0000x1x0'], [[4, 5], [6, 7]])], [('plain binary toggles', ['0101111110'], [[1, 3], [2, 9]]), ('edges through unknown and floating', ['0x1z0'], [[1, 2], [3, 4]]), ('unknown to floating is no edge', ['xxxxxzx1z'], [[7], [8]]), ('floating rising and falling', ['z1z0zzzzz'], [[1, 4], [2, 3]]), ('high to floating then low', ['1xxxxxz0'], [[], [1, 7]]), ('starts high without a predecessor', ['1100000'], [[], [2]]), ('low through unknown to high', ['00000x1x0'], [[5, 6], [7, 8]])]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
plain binary toggles[[1, 3], [2, 5]][[1, 3], [2, 5]]Passed
edges through unknown and floating[[1, 2], [3, 4]][[1, 2], [3, 4]]Passed
unknown to floating is no edge[[3], [4]][[3], [4]]Passed
floating rising and falling[[1, 4], [2, 3]][[1, 4], [2, 3]]Passed
high to floating then low[[], [1, 3]][[], [1, 3]]Passed
starts high without a predecessor[[], [2]][[], [2]]Passed
low through unknown to high[[1, 2], [3, 4]][[1, 2], [3, 4]]Passed

SHA-256 / 346ada859aea2c3bdca6de35f6c1b39dc83946394b269fa1c49ee6e98fc2839a

Verification & scope

A deterministic bounded teaching model of one simulator rule set; the contract is stipulated and is not a claim of conformance to any HDL standard or commercial simulator. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.

Observations recorded using Python 3.12.14 at 2026-09-29T14:51:14.127880+00:00.

Case digest / 186e1568863cad435dd6e755c3c27380b4e335289f8c62cfea855f8a664e9867