Formal & assertion-based verification

Formal constraints & assumptions

When you run formal verification, the tool is allowed to feed your design *any* input it can dream up — including patterns the real world would never produce. Left unchecked it will gleefully find 'bugs' that only happen if the input protocol is violated, drowning you in false failures. Constraints (written as `assume` properties) are the fence you build around the input space: 'assume the bus master always follows the AXI handshake.' Now the tool only hunts for bugs reachable under legal inputs — exactly the bugs that matter.

This is the heart of the *assume-guarantee* contract. Each block guarantees its outputs are well-behaved *provided* its inputs obey the assumptions; the neighbouring block then assumes those guarantees as its own inputs. The danger is the double-edged sword: an *over-constraint* secretly forbids legal inputs and can hide a real bug (the tool never explores the failing scenario), while an *under-constraint* lets in illegal inputs and floods you with spurious counterexamples. Getting the constraints exactly right — tight enough to be realistic, loose enough to miss nothing — is the single most skilled, error-prone part of formal verification.

The cardinal sin of formal verification is the over-constraint that hides a real bug — your proof says 'property holds' but only because the tool was forbidden from exercising the failing case. Best practice: keep constraints minimal, review them adversarially, and sanity-check with cover properties to confirm the legal-but-interesting scenarios are still reachable.

Also called
assume-guaranteeconstraint假設約束