fix: iterative evaluation for sequential circuits + debug logs

Replace single-pass recursive evaluation with iterative fixed-point
evaluation that runs multiple passes until all gate values stabilize.
Crucially, gate values are NO LONGER reset to 0 before evaluation,
which preserves latch/flip-flop memory state.

Add console logs for toggle, wire, and evaluation stability debugging.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jose Luis
2026-03-20 03:59:26 +01:00
parent 2384c489b9
commit a4292b42cf
2 changed files with 60 additions and 24 deletions

View File

@@ -100,12 +100,18 @@ export function initEvents() {
if (state.connecting) {
if (state.connecting.portType === 'output' && port.type === 'input') {
state.connections = state.connections.filter(c => !(c.to === port.gate.id && c.toPort === port.index));
state.connections.push({ from: state.connecting.gate.id, fromPort: state.connecting.portIndex, to: port.gate.id, toPort: port.index });
const conn = { from: state.connecting.gate.id, fromPort: state.connecting.portIndex, to: port.gate.id, toPort: port.index };
state.connections.push(conn);
console.log(`[wire] ${conn.from}:${conn.fromPort}${conn.to}:${conn.toPort}`);
evaluateAll();
console.log('[state]', state.gates.map(g => `${g.type}#${g.id}=${g.value}`).join(', '));
} else if (state.connecting.portType === 'input' && port.type === 'output') {
state.connections = state.connections.filter(c => !(c.to === state.connecting.gate.id && c.toPort === state.connecting.portIndex));
state.connections.push({ from: port.gate.id, fromPort: port.index, to: state.connecting.gate.id, toPort: state.connecting.portIndex });
const conn = { from: port.gate.id, fromPort: port.index, to: state.connecting.gate.id, toPort: state.connecting.portIndex };
state.connections.push(conn);
console.log(`[wire] ${conn.from}:${conn.fromPort}${conn.to}:${conn.toPort}`);
evaluateAll();
console.log('[state]', state.gates.map(g => `${g.type}#${g.id}=${g.value}`).join(', '));
}
state.connecting = null;
} else {
@@ -131,7 +137,10 @@ export function initEvents() {
const gate = state.dragging;
if (gate.type === 'INPUT' || gate.type === 'CLOCK') {
gate.value = gate.value ? 0 : 1;
console.log(`[toggle] ${gate.type}#${gate.id}${gate.value}`);
evaluateAll(true); // record waveform on intentional toggle
// Log all gate values after evaluation
console.log('[state]', state.gates.map(g => `${g.type}#${g.id}=${g.value}`).join(', '));
}
}
state.dragging = null;