FA-89186 / Digital logic simulation / Open access
JK flip-flop holds instead of toggling · case 01
J=K=1 leaves the output unchanged.
ROOT CAUSE
The J=K=1 row of the characteristic table is implemented as hold.
VERIFIED REPAIR
Toggle the output when J and K are both 1, keeping x as x.
Unsuccessful approach: Resolving a toggled unknown to 0 invents a definite state.
Case contract
Input [kind, q0, ins] with one [a, b] pair per clock edge. jk (a=J, b=K): 00 hold, 10 set, 01 reset, 11 toggle. sr (a=S, b=R): 10 set, 01 reset, 00 hold, 11 is forbidden and makes q 'x'. t (a=T): 1 toggles, 0 holds, 'x' makes q 'x'. Toggling 'x' gives 'x'. Return q after each edge.
Why this case matters
Behavioural flip-flop primitives in gate-level libraries must reproduce characteristic tables, including unknown handling.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(*args):
kind, q, ins = args
def tog(v):
return {0: 1, 1: 0}.get(v, 'x')
out = []
for a, b in ins:
if kind == 't':
if a == 'x': q = 'x'
elif a == 1: q = tog(q)
elif kind == 'jk':
if a == 1 and b == 1: q = q
elif a == 1: q = 1
elif b == 1: q = 0
else:
if a == 1 and b == 1: q = 'x'
elif (a, b) == (1, 0): q = 1
elif (a, b) == (0, 1): q = 0
out.append(q)
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('jk toggles from known state', ['jk', 0, [[1, 0], [0, 0], [1, 1], [0, 1]]], [1, 1, 0, 0]), ('jk toggle from unknown', ['jk', 'x', [[1, 1], [1, 0], [1, 1]]], ['x', 1, 0]), ('jk reset only', ['jk', 1, [[0, 1], [0, 0], [1, 0], [0, 1]]], [0, 0, 1, 0]), ('sr forbidden input', ['sr', 0, [[1, 0], [1, 1], [0, 0], [0, 1], [1, 0]]], [1, 'x', 'x', 0, 1]), ('sr hold and set', ['sr', 1, [[0, 0], [0, 1], [1, 0]]], [1, 0, 1]), ('t unknown enable', ['t', 1, [[1, 0], ['x', 0], [1, 0], [0, 0]]], [0, 'x', 'x', 'x']), ('t toggles', ['t', 0, [[1, 0], [1, 0], [0, 0]]], [1, 0, 0])], [('jk toggles from known state', ['jk', 0, [[1, 0], [0, 0], [1, 1], [1, 1], [0, 1]]], [1, 1, 0, 1, 0]), ('jk toggle from unknown', ['jk', 'x', [[1, 1], [1, 0], [1, 1]]], ['x', 1, 0]), ('jk reset only', ['jk', 1, [[0, 1], [0, 0], [1, 0]]], [0, 0, 1]), ('sr forbidden input', ['sr', 0, [[1, 0], [1, 1], [0, 0], [0, 1], [1, 0], [1, 0]]], [1, 'x', 'x', 0, 1, 1]), ('sr hold and set', ['sr', 1, [[0, 0], [0, 1], [1, 0]]], [1, 0, 1]), ('t unknown enable', ['t', 1, [[1, 0], ['x', 0], [1, 0], [0, 0], [0, 0]]], [0, 'x', 'x', 'x', 'x']), ('t toggles', ['t', 0, [[1, 0], [1, 0], [1, 0], [0, 0]]], [1, 0, 1, 1])], [('jk toggles from known state', ['jk', 0, [[1, 0], [0, 0], [1, 1], [1, 1], [1, 1], [0, 1]]], [1, 1, 0, 1, 0, 0]), ('jk toggle from unknown', ['jk', 'x', [[1, 1], [1, 0], [1, 1]]], ['x', 1, 0]), ('jk reset only', ['jk', 1, [[0, 1], [0, 0], [1, 0], [0, 1]]], [0, 0, 1, 0]), ('sr forbidden input', ['sr', 0, [[1, 0], [1, 1], [0, 0], [0, 1], [1, 0], [1, 0], [1, 0]]], [1, 'x', 'x', 0, 1, 1, 1]), ('sr hold and set', ['sr', 1, [[0, 0], [0, 1], [1, 0]]], [1, 0, 1]), ('t unknown enable', ['t', 1, [[1, 0], ['x', 0], [1, 0], [0, 0], [0, 0], [0, 0]]], [0, 'x', 'x', 'x', 'x', 'x']), ('t toggles', ['t', 0, [[1, 0], [1, 0], [1, 0], [1, 0], [0, 0]]], [1, 0, 1, 0, 0])], [('jk toggles from known state', ['jk', 0, [[1, 0], [0, 0], [1, 1], [1, 1], [1, 1], [1, 1], [0, 1]]], [1, 1, 0, 1, 0, 1, 0]), ('jk toggle from unknown', ['jk', 'x', [[1, 1], [1, 0], [1, 1]]], ['x', 1, 0]), ('jk reset only', ['jk', 1, [[0, 1], [0, 0], [1, 0]]], [0, 0, 1]), ('sr forbidden input', ['sr', 0, [[1, 0], [1, 1], [0, 0], [0, 1], [1, 0], [1, 0], [1, 0], [1, 0]]], [1, 'x', 'x', 0, 1, 1, 1, 1]), ('sr hold and set', ['sr', 1, [[0, 0], [0, 1], [1, 0]]], [1, 0, 1]), ('t unknown enable', ['t', 1, [[1, 0], ['x', 0], [1, 0], [0, 0], [0, 0], [0, 0], [0, 0]]], [0, 'x', 'x', 'x', 'x', 'x', 'x']), ('t toggles', ['t', 0, [[1, 0], [1, 0], [1, 0], [1, 0], [1, 0], [0, 0]]], [1, 0, 1, 0, 1, 1])], [('jk toggles from known state', ['jk', 0, [[1, 0], [0, 0], [1, 1], [1, 1], [1, 1], [1, 1], [1, 1], [0, 1]]], [1, 1, 0, 1, 0, 1, 0, 0]), ('jk toggle from unknown', ['jk', 'x', [[1, 1], [1, 0], [1, 1]]], ['x', 1, 0]), ('jk reset only', ['jk', 1, [[0, 1], [0, 0], [1, 0], [0, 1]]], [0, 0, 1, 0]), ('sr forbidden input', ['sr', 0, [[1, 0], [1, 1], [0, 0], [0, 1], [1, 0], [1, 0], [1, 0], [1, 0], [1, 0]]], [1, 'x', 'x', 0, 1, 1, 1, 1, 1]), ('sr hold and set', ['sr', 1, [[0, 0], [0, 1], [1, 0]]], [1, 0, 1]), ('t unknown enable', ['t', 1, [[1, 0], ['x', 0], [1, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]], [0, 'x', 'x', 'x', 'x', 'x', 'x', 'x']), ('t toggles', ['t', 0, [[1, 0], [1, 0], [1, 0], [1, 0], [1, 0], [1, 0], [0, 0]]], [1, 0, 1, 0, 1, 0, 0])]]
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| jk toggles from known state | [1, 1, 1, 0] | [1, 1, 0, 0] | Failed |
| jk toggle from unknown | ['x', 1, 1] | ['x', 1, 0] | Failed |
| jk reset only | [0, 0, 1, 0] | [0, 0, 1, 0] | Passed |
| sr forbidden input | [1, 'x', 'x', 0, 1] | [1, 'x', 'x', 0, 1] | Passed |
| sr hold and set | [1, 0, 1] | [1, 0, 1] | Passed |
| t unknown enable | [0, 'x', 'x', 'x'] | [0, 'x', 'x', 'x'] | Passed |
| t toggles | [1, 0, 0] | [1, 0, 0] | Passed |
SHA-256 / 5dc4e185806b2d23a9bb8280d2f593558213d30f50692100f2cad74b4ff8e7c3
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(*args):
kind, q, ins = args
def tog(v):
return {0: 1, 1: 0}.get(v, 'x')
out = []
for a, b in ins:
if kind == 't':
if a == 'x': q = 'x'
elif a == 1: q = tog(q)
elif kind == 'jk':
if a == 1 and b == 1: q = 1 - q if q != 'x' else 0
elif a == 1: q = 1
elif b == 1: q = 0
else:
if a == 1 and b == 1: q = 'x'
elif (a, b) == (1, 0): q = 1
elif (a, b) == (0, 1): q = 0
out.append(q)
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('jk toggles from known state', ['jk', 0, [[1, 0], [0, 0], [1, 1], [0, 1]]], [1, 1, 0, 0]), ('jk toggle from unknown', ['jk', 'x', [[1, 1], [1, 0], [1, 1]]], ['x', 1, 0]), ('jk reset only', ['jk', 1, [[0, 1], [0, 0], [1, 0], [0, 1]]], [0, 0, 1, 0]), ('sr forbidden input', ['sr', 0, [[1, 0], [1, 1], [0, 0], [0, 1], [1, 0]]], [1, 'x', 'x', 0, 1]), ('sr hold and set', ['sr', 1, [[0, 0], [0, 1], [1, 0]]], [1, 0, 1]), ('t unknown enable', ['t', 1, [[1, 0], ['x', 0], [1, 0], [0, 0]]], [0, 'x', 'x', 'x']), ('t toggles', ['t', 0, [[1, 0], [1, 0], [0, 0]]], [1, 0, 0])], [('jk toggles from known state', ['jk', 0, [[1, 0], [0, 0], [1, 1], [1, 1], [0, 1]]], [1, 1, 0, 1, 0]), ('jk toggle from unknown', ['jk', 'x', [[1, 1], [1, 0], [1, 1]]], ['x', 1, 0]), ('jk reset only', ['jk', 1, [[0, 1], [0, 0], [1, 0]]], [0, 0, 1]), ('sr forbidden input', ['sr', 0, [[1, 0], [1, 1], [0, 0], [0, 1], [1, 0], [1, 0]]], [1, 'x', 'x', 0, 1, 1]), ('sr hold and set', ['sr', 1, [[0, 0], [0, 1], [1, 0]]], [1, 0, 1]), ('t unknown enable', ['t', 1, [[1, 0], ['x', 0], [1, 0], [0, 0], [0, 0]]], [0, 'x', 'x', 'x', 'x']), ('t toggles', ['t', 0, [[1, 0], [1, 0], [1, 0], [0, 0]]], [1, 0, 1, 1])], [('jk toggles from known state', ['jk', 0, [[1, 0], [0, 0], [1, 1], [1, 1], [1, 1], [0, 1]]], [1, 1, 0, 1, 0, 0]), ('jk toggle from unknown', ['jk', 'x', [[1, 1], [1, 0], [1, 1]]], ['x', 1, 0]), ('jk reset only', ['jk', 1, [[0, 1], [0, 0], [1, 0], [0, 1]]], [0, 0, 1, 0]), ('sr forbidden input', ['sr', 0, [[1, 0], [1, 1], [0, 0], [0, 1], [1, 0], [1, 0], [1, 0]]], [1, 'x', 'x', 0, 1, 1, 1]), ('sr hold and set', ['sr', 1, [[0, 0], [0, 1], [1, 0]]], [1, 0, 1]), ('t unknown enable', ['t', 1, [[1, 0], ['x', 0], [1, 0], [0, 0], [0, 0], [0, 0]]], [0, 'x', 'x', 'x', 'x', 'x']), ('t toggles', ['t', 0, [[1, 0], [1, 0], [1, 0], [1, 0], [0, 0]]], [1, 0, 1, 0, 0])], [('jk toggles from known state', ['jk', 0, [[1, 0], [0, 0], [1, 1], [1, 1], [1, 1], [1, 1], [0, 1]]], [1, 1, 0, 1, 0, 1, 0]), ('jk toggle from unknown', ['jk', 'x', [[1, 1], [1, 0], [1, 1]]], ['x', 1, 0]), ('jk reset only', ['jk', 1, [[0, 1], [0, 0], [1, 0]]], [0, 0, 1]), ('sr forbidden input', ['sr', 0, [[1, 0], [1, 1], [0, 0], [0, 1], [1, 0], [1, 0], [1, 0], [1, 0]]], [1, 'x', 'x', 0, 1, 1, 1, 1]), ('sr hold and set', ['sr', 1, [[0, 0], [0, 1], [1, 0]]], [1, 0, 1]), ('t unknown enable', ['t', 1, [[1, 0], ['x', 0], [1, 0], [0, 0], [0, 0], [0, 0], [0, 0]]], [0, 'x', 'x', 'x', 'x', 'x', 'x']), ('t toggles', ['t', 0, [[1, 0], [1, 0], [1, 0], [1, 0], [1, 0], [0, 0]]], [1, 0, 1, 0, 1, 1])], [('jk toggles from known state', ['jk', 0, [[1, 0], [0, 0], [1, 1], [1, 1], [1, 1], [1, 1], [1, 1], [0, 1]]], [1, 1, 0, 1, 0, 1, 0, 0]), ('jk toggle from unknown', ['jk', 'x', [[1, 1], [1, 0], [1, 1]]], ['x', 1, 0]), ('jk reset only', ['jk', 1, [[0, 1], [0, 0], [1, 0], [0, 1]]], [0, 0, 1, 0]), ('sr forbidden input', ['sr', 0, [[1, 0], [1, 1], [0, 0], [0, 1], [1, 0], [1, 0], [1, 0], [1, 0], [1, 0]]], [1, 'x', 'x', 0, 1, 1, 1, 1, 1]), ('sr hold and set', ['sr', 1, [[0, 0], [0, 1], [1, 0]]], [1, 0, 1]), ('t unknown enable', ['t', 1, [[1, 0], ['x', 0], [1, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]], [0, 'x', 'x', 'x', 'x', 'x', 'x', 'x']), ('t toggles', ['t', 0, [[1, 0], [1, 0], [1, 0], [1, 0], [1, 0], [1, 0], [0, 0]]], [1, 0, 1, 0, 1, 0, 0])]]
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| jk toggles from known state | [1, 1, 0, 0] | [1, 1, 0, 0] | Passed |
| jk toggle from unknown | [0, 1, 0] | ['x', 1, 0] | Failed |
| jk reset only | [0, 0, 1, 0] | [0, 0, 1, 0] | Passed |
| sr forbidden input | [1, 'x', 'x', 0, 1] | [1, 'x', 'x', 0, 1] | Passed |
| sr hold and set | [1, 0, 1] | [1, 0, 1] | Passed |
| t unknown enable | [0, 'x', 'x', 'x'] | [0, 'x', 'x', 'x'] | Passed |
| t toggles | [1, 0, 0] | [1, 0, 0] | Passed |
SHA-256 / 7d378ea1208b14856387f5970ad41ab9061b2a5afdd9908060b716760c34f1f4
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(*args):
kind, q, ins = args
def tog(v):
return {0: 1, 1: 0}.get(v, 'x')
out = []
for a, b in ins:
if kind == 't':
if a == 'x': q = 'x'
elif a == 1: q = tog(q)
elif kind == 'jk':
if a == 1 and b == 1: q = tog(q)
elif a == 1: q = 1
elif b == 1: q = 0
else:
if a == 1 and b == 1: q = 'x'
elif (a, b) == (1, 0): q = 1
elif (a, b) == (0, 1): q = 0
out.append(q)
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('jk toggles from known state', ['jk', 0, [[1, 0], [0, 0], [1, 1], [0, 1]]], [1, 1, 0, 0]), ('jk toggle from unknown', ['jk', 'x', [[1, 1], [1, 0], [1, 1]]], ['x', 1, 0]), ('jk reset only', ['jk', 1, [[0, 1], [0, 0], [1, 0], [0, 1]]], [0, 0, 1, 0]), ('sr forbidden input', ['sr', 0, [[1, 0], [1, 1], [0, 0], [0, 1], [1, 0]]], [1, 'x', 'x', 0, 1]), ('sr hold and set', ['sr', 1, [[0, 0], [0, 1], [1, 0]]], [1, 0, 1]), ('t unknown enable', ['t', 1, [[1, 0], ['x', 0], [1, 0], [0, 0]]], [0, 'x', 'x', 'x']), ('t toggles', ['t', 0, [[1, 0], [1, 0], [0, 0]]], [1, 0, 0])], [('jk toggles from known state', ['jk', 0, [[1, 0], [0, 0], [1, 1], [1, 1], [0, 1]]], [1, 1, 0, 1, 0]), ('jk toggle from unknown', ['jk', 'x', [[1, 1], [1, 0], [1, 1]]], ['x', 1, 0]), ('jk reset only', ['jk', 1, [[0, 1], [0, 0], [1, 0]]], [0, 0, 1]), ('sr forbidden input', ['sr', 0, [[1, 0], [1, 1], [0, 0], [0, 1], [1, 0], [1, 0]]], [1, 'x', 'x', 0, 1, 1]), ('sr hold and set', ['sr', 1, [[0, 0], [0, 1], [1, 0]]], [1, 0, 1]), ('t unknown enable', ['t', 1, [[1, 0], ['x', 0], [1, 0], [0, 0], [0, 0]]], [0, 'x', 'x', 'x', 'x']), ('t toggles', ['t', 0, [[1, 0], [1, 0], [1, 0], [0, 0]]], [1, 0, 1, 1])], [('jk toggles from known state', ['jk', 0, [[1, 0], [0, 0], [1, 1], [1, 1], [1, 1], [0, 1]]], [1, 1, 0, 1, 0, 0]), ('jk toggle from unknown', ['jk', 'x', [[1, 1], [1, 0], [1, 1]]], ['x', 1, 0]), ('jk reset only', ['jk', 1, [[0, 1], [0, 0], [1, 0], [0, 1]]], [0, 0, 1, 0]), ('sr forbidden input', ['sr', 0, [[1, 0], [1, 1], [0, 0], [0, 1], [1, 0], [1, 0], [1, 0]]], [1, 'x', 'x', 0, 1, 1, 1]), ('sr hold and set', ['sr', 1, [[0, 0], [0, 1], [1, 0]]], [1, 0, 1]), ('t unknown enable', ['t', 1, [[1, 0], ['x', 0], [1, 0], [0, 0], [0, 0], [0, 0]]], [0, 'x', 'x', 'x', 'x', 'x']), ('t toggles', ['t', 0, [[1, 0], [1, 0], [1, 0], [1, 0], [0, 0]]], [1, 0, 1, 0, 0])], [('jk toggles from known state', ['jk', 0, [[1, 0], [0, 0], [1, 1], [1, 1], [1, 1], [1, 1], [0, 1]]], [1, 1, 0, 1, 0, 1, 0]), ('jk toggle from unknown', ['jk', 'x', [[1, 1], [1, 0], [1, 1]]], ['x', 1, 0]), ('jk reset only', ['jk', 1, [[0, 1], [0, 0], [1, 0]]], [0, 0, 1]), ('sr forbidden input', ['sr', 0, [[1, 0], [1, 1], [0, 0], [0, 1], [1, 0], [1, 0], [1, 0], [1, 0]]], [1, 'x', 'x', 0, 1, 1, 1, 1]), ('sr hold and set', ['sr', 1, [[0, 0], [0, 1], [1, 0]]], [1, 0, 1]), ('t unknown enable', ['t', 1, [[1, 0], ['x', 0], [1, 0], [0, 0], [0, 0], [0, 0], [0, 0]]], [0, 'x', 'x', 'x', 'x', 'x', 'x']), ('t toggles', ['t', 0, [[1, 0], [1, 0], [1, 0], [1, 0], [1, 0], [0, 0]]], [1, 0, 1, 0, 1, 1])], [('jk toggles from known state', ['jk', 0, [[1, 0], [0, 0], [1, 1], [1, 1], [1, 1], [1, 1], [1, 1], [0, 1]]], [1, 1, 0, 1, 0, 1, 0, 0]), ('jk toggle from unknown', ['jk', 'x', [[1, 1], [1, 0], [1, 1]]], ['x', 1, 0]), ('jk reset only', ['jk', 1, [[0, 1], [0, 0], [1, 0], [0, 1]]], [0, 0, 1, 0]), ('sr forbidden input', ['sr', 0, [[1, 0], [1, 1], [0, 0], [0, 1], [1, 0], [1, 0], [1, 0], [1, 0], [1, 0]]], [1, 'x', 'x', 0, 1, 1, 1, 1, 1]), ('sr hold and set', ['sr', 1, [[0, 0], [0, 1], [1, 0]]], [1, 0, 1]), ('t unknown enable', ['t', 1, [[1, 0], ['x', 0], [1, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]], [0, 'x', 'x', 'x', 'x', 'x', 'x', 'x']), ('t toggles', ['t', 0, [[1, 0], [1, 0], [1, 0], [1, 0], [1, 0], [1, 0], [0, 0]]], [1, 0, 1, 0, 1, 0, 0])]]
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| jk toggles from known state | [1, 1, 0, 0] | [1, 1, 0, 0] | Passed |
| jk toggle from unknown | ['x', 1, 0] | ['x', 1, 0] | Passed |
| jk reset only | [0, 0, 1, 0] | [0, 0, 1, 0] | Passed |
| sr forbidden input | [1, 'x', 'x', 0, 1] | [1, 'x', 'x', 0, 1] | Passed |
| sr hold and set | [1, 0, 1] | [1, 0, 1] | Passed |
| t unknown enable | [0, 'x', 'x', 'x'] | [0, 'x', 'x', 'x'] | Passed |
| t toggles | [1, 0, 0] | [1, 0, 0] | Passed |
SHA-256 / 38c4d33fc01170e426026d3404ea64bd5539f0d8eaaac78747ef053481d699a5
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.911198+00:00.
Case digest / 37b1aacec231859ab921b5eb534e87bc605f7b7109395cbe0cfdbfc315ae04cf