Interviews
Formal Basics Interview Questions
Practise the question, then the follow-ups an interviewer asks next.
Start with a Question TreeAI Mock Interview
- 6
- Question trees
- 42
- Follow-ups
- 25
- Wrong answers explained
- 12
- Runnable on a simulator
Flagship Questions · With follow-ups
Question Trees
Each question opens into the follow-ups an interviewer asks next, the wrong answers people give, and what a fresher's and a senior's answer sound like.
-
Formal Verification vs Simulation
What is the difference between formal verification and simulation, and when would you pick each? 8 follow-ups · 4 pitfalls · 1 runnable- Asked at Qualcomm
- Likely at Infineon
- Likely at Micron
-
Assert, Assume and Cover in Formal
In a formal run, what doassert,assumeandcovereach tell the tool to do? 6 follow-ups · 4 pitfalls · 2 runnable- Likely at AMD
- Likely at Intel
-
What a Bounded Pass Promises
The tool reports BMC PASS at depth 20 on an idle-timeout block. Your manager asks whether the block is verified. What do you say? 5 follow-ups · 4 pitfalls · 2 runnable -
Reading a Formal Counterexample
A formal run fails at step 7 and hands you a trace. How do you read it, and how do you tell a real bug from a problem in your bench? 7 follow-ups · 4 pitfalls · 1 runnable -
Reset and the Initial State in Formal
Your first formal run on a decade counter fails at step 1 withcount = 12. The RTL has a synchronous reset. What went wrong? 10 follow-ups · 6 pitfalls · 5 runnable -
Safety and Liveness Properties
What is the difference between a safety property and a liveness property, and how does each one fail? 6 follow-ups · 3 pitfalls · 1 runnable
No question matches these filters.
Quick revision · One flat list
Question Bank
All 36 Formal Basics questions, main and follow-up. Open a track, then a topic. Answer out loud first, then open the short answer.
Jump to a Track
36 questions · 6 topicsFormal Basics
Formal Verification vs Simulation8
What is the difference between formal verification and simulation, and when would you pick each? L0L1
Simulation checks the paths your stimulus happens to drive, so a rare corner is found only if some test reaches it. Formal treats the inputs as free. It asks a solver whether any input sequence breaks a property, within a bound or for all time. Pick formal for control logic with deep corners such as arbiters, FIFOs, protocol rules and registers. Keep simulation for long end-to-end flows, performance and whole-chip behaviour.
QuestionPractise Formal Verification vs Simulation →Why can a bug survive a million random cycles and then fall out of a formal run in seconds? L0L1
A simulation is one path. A million cycles visit at most a million states, out of up to 2 to the power of the flop count. BMC at depth k reasons about every input sequence of length k from reset in one solver query. The solver picks the inputs that break the property, so a rare three-cycle pattern costs it nothing extra.
Follow-upPractise Why Formal Finds What a Million Cycles Miss →Which blocks are poor candidates for formal, and what do you do about them? L1L2
Formal struggles when a property's cone is deep or hard: long counters, wide multipliers, big memories and whole-chip flows. A bounded run then stops short of the behaviour and a proof may never finish. One option is to change the question with cut points, abstraction and smaller parameters. The other is to leave that part to simulation and prove the control logic around it.
Follow-upPractise Blocks That Resist Formal →Why does a 16-bit timeout counter make a bounded proof hopeless, and what do you do instead? L1L2
Reaching expiry from reset takes as many steps as the count. BMC must unroll every one of them, so the required depth runs into the tens of thousands. Instead, abstract the counter to the few values that matter and prove the abstraction on the real counter in a side run. A one-transition property can also be proven by induction at full width without ever reaching expiry.
Follow-upPractise Why a Wide Counter Defeats BMC →You replace the 16-bit timeout counter with an abstract one that may expire at any time. Why is that sound, and what can it break? L2L3
The abstract counter can do everything the real one does, plus more, such as expiring early. So a pass on the abstract model holds for the real design. The extra behaviour can cause false failures, for example an early timeout. Check each failure against the real counter, and prove the values you kept on the real design.
Follow-upPractise Is the Abstract Counter Sound →A block passed full formal proofs and still had a bug in silicon. How can that happen? L2L3
The proof was true of what was written, not of what was meant. Common causes are a missing or weak property, or an assumption that removed legal inputs. Others are a bounded result read as a proof, or a bug outside every property's cone. The defences are a spec checklist, covers under the assumptions, a stated required depth and a cone map.
Follow-upPractise A Proven Block with a Silicon Bug →You own verification of a new IP. How do you decide what formal covers and what simulation covers? L3
Split by question, not by team. Formal takes control logic whose rules fit in a few cycles: protocol compliance, arbitration, FIFO and credit invariants, registers, connectivity and deadlock. Simulation keeps data flows across many blocks, long scenarios, performance and firmware interaction. Every formal assumption is also bound into simulation as an assertion, so a wrong assumption is caught at system level.
Follow-upPractise Splitting an IP Between Formal and Simulation →A refresh event happens only every few thousand cycles, far past any depth your proofs reach. Compare full formal with a semiformal search for bugs around that event. L2L3
Full formal searches every trace from reset, so a few thousand cycles of depth is out of reach. Semiformal starts the solver from a waypoint instead: a simulation or cover trace that has already run close to the event. It then searches exhaustively from there. It finds deep bugs that neither method finds alone. But it proves nothing about the states it skipped, so it counts as bug hunting, not sign-off.
Follow-upPractise Full Formal vs Semiformal Search →Assert, Assume and Cover in Formal5
In a formal run, what do assert, assume and cover each tell the tool to do? L0L1
An assertion is a goal: the tool searches for any legal input sequence that breaks it. An assumption is taken as true, so it removes input sequences from the search. A cover asks the tool to reach a condition and return a trace that does. The working rule is to assume what the environment does, assert what the design does and cover what should be possible.
QuestionPractise Assert, Assume and Cover in Formal →Why should the first run on a new formal bench be covers, not assertions? L1
A cover shows the design moving under your assumptions: reset releases, the FIFO fills, each state is entered. If the bench is over-constrained, the covers come back unreached before any assertion can mislead you with a pass. In this run the arbiter's output is assumed one-hot, and the cover of a double grant is unreached.
Follow-upPractise Why Covers Come Before Asserts →The same SVA file is compiled into the simulation testbench. What happens to the assume and cover statements there? L1L2
A simulator checks an assume exactly like an assert. So the system testbench tells you when the real environment breaks a block-level assumption. Covers are counted as they are hit, and restrict is ignored. Binding block assumptions into system simulation is the cheapest way to validate them.
What if a block assumption, bound into system simulation, fires on day 40? What does it tell you, and what do you do? L2
The real neighbour broke a rule that the block proof relied on. So the block proof does not cover that traffic. Decide from the spec which side is wrong. Either fix the neighbour, or relax the assumption and rerun the proof, which may now fail.
Follow-upPractise A Block Assumption Fires in System Simulation →How does a formal cover differ from a covergroup bin that simulation hits? L1L2
A covergroup bin counts what your tests happened to do. A formal cover asks whether any legal input sequence can reach the condition and returns the shortest trace that does. An unreached formal cover within a bound only says the depth was too short or an assumption blocks it. A proof of the negation is what makes a bin truly unreachable.
Follow-upPractise A Formal Cover vs a Covergroup Bin →What a Bounded Pass Promises5
The tool reports BMC PASS at depth 20 on an idle-timeout block. Your manager asks whether the block is verified. What do you say? L0L1
It means no input sequence breaks the property within the first 20 steps from reset, and nothing more. A bug that needs a longer run, such as a counter reaching its limit, is invisible at that depth. Either compute the depth the logic needs and show covers reach it, or run a prove mode for an unbounded answer.
QuestionPractise What a Bounded Pass Promises →How do you work out the depth a bounded proof must reach before you trust it? L2L3
Start from the deepest counter in the property's cone, the longest transaction and the property's own window. Then add the tool's step offset. Check the number with covers: the deepest interesting behaviour must be reached inside the bound. The book's guideline is to prove assertions deeper than the longest cover trace, ideally about twice as deep.
Follow-upPractise Working Out the Required Depth →You computed a required depth of 30 and proved to 30. How can the result still miss a bug? L2L3
The number is only as good as its inputs. A counter you missed in the cone, a longer transaction or a wrong step offset makes 30 too small. Covers check it: the deepest interesting state must be reached inside the bound. A depth sweep, where a planted bug fails near the predicted depth, also checks the arithmetic.
Follow-upPractise A Required Depth That Was Too Small →What does a prove mode give you that BMC does not, and what does an UNKNOWN result mean? L1L2
Prove mode runs k-induction (an induction proof over k steps) or IC3/PDR (an engine that builds its own invariant). It can return a PASS that holds for all time. UNKNOWN means the base case passed but the induction step did not, so no proof has been found. It is an open item, never a pass, and it can sit on a real bug deeper than the base case. On the buggy idle timer here, prove at k = 2 reports UNKNOWN rather than FAIL.
Follow-upPractise BMC vs Prove Mode, and What UNKNOWN Means →Your full proofs will not converge before tape-out. Can you sign off with bounded proofs instead? L3
Yes, if the bound is argued, not hoped. The page must show the required depth from the counters and transactions, and a run that reaches it. It must also show covers of the deepest behaviour inside the bound. The page reports the result as bounded, with the depth, the tool version and the date. It also states the risk of a deeper bug.
Follow-upPractise Bounded Proofs at Sign-Off →Reading a Formal Counterexample6
A formal run fails at step 7 and hands you a trace. How do you read it, and how do you tell a real bug from a problem in your bench? L0L1
Start at the failing step and walk backwards to the first value that set the design on the wrong path. Then sort the cause into one of four: an RTL bug, a missing assumption, a wrong property, or reset not modelled. The state at step 0 and the inputs the solver chose usually decide it. An input sequence the real environment never produces calls for an assumption, not an RTL change.
QuestionPractise Reading a Formal Counterexample →Why are formal counterexamples usually much shorter than the simulation failures for the same bug? L1
BMC checks depth 1, then 2, and so on, and stops at the first satisfiable depth, so no shorter failing trace exists. The solver also chooses every input directly instead of waiting for random stimulus to line up. An IC3/PDR counterexample (from the engine that builds its own invariant) starts at reset too but need not be the shortest.
Follow-upPractise Why Formal Traces Are Short →Your counterexample fails at step 1, before any request has arrived. What do you check first? L1
Check how the design starts. A failure that early usually has one of two causes. Either reset was not assumed in the first step, or a flop with no reset started at a value the solver chose. Look at step 0. If a register holds a value reset would never give it, fix the bench or add the reset, not the logic.
Follow-upPractise A Failure One Step After Reset →What if the unreset register is set by firmware at boot, so the hardware team refuses to add a reset? L1L2
Then the start value is an assumption, not a fact. Write it as an initial-state assumption that the register holds its boot value. Put it on the sign-off list, so someone checks it against the boot code. Add a cover that the block still runs, so the assumption did not empty the bench.
Follow-upPractise A Register That Firmware Initialises →Compare debugging a formal counterexample with debugging a failing random simulation. L1L2
A simulation failure is one run, often thousands of cycles long, with the cause buried somewhere in the middle. A formal trace is short and stands for a whole family of failures. If it shows an illegal input, you add an assumption and re-solve. The tool then returns another trace or proves the case is gone, which new random seeds can never tell you.
Follow-upPractise Debugging a Counterexample vs a Simulation Failure →Your team brings up formal on a new block and reports forty failures in one morning. How do you triage them? L3
Expect most early failures to be environment problems, not RTL bugs. Bucket them by cause from step 0 and the solver-chosen inputs, fix reset and missing assumptions first, and rerun; many failures collapse together. Each assumption added is written from a spec row, reviewed, and paired with a cover. Only the failures that survive go to the designer as bugs.
Follow-upPractise Triaging Forty Formal Failures →Reset and the Initial State in Formal7
Your first formal run on a decade counter fails at step 1 with count = 12. The RTL has a synchronous reset. What went wrong? L0L1
Nothing told the tool how the design starts, so every state, including count = 12, was a legal initial state. Assume reset in the first step, for example if ($initstate) assume(rst), or declare initial values. A flop with no reset or initial value stays a free choice at step 0. The solver picks whichever value breaks the property.
Why does a formal tool treat an unreset flop as any value, instead of X as simulation does? L1
Formal models are two-valued, and silicon powers up to some real 0 or 1 in each flop. Leaving the start value free lets the solver try every possibility in one run. Four-state simulation instead carries an X that if statements can silently resolve, so it may never show the bad value.
Compare assuming reset in the first step, declaring initial values and holding reset with a small counter. L1L2
All three make the decade counter pass at depth 20 in the lesson. Assuming reset at $initstate checks the real reset logic and is closest to silicon. Declared initial values skip the reset path, so a bug in it can hide. A reset counter models a multi-cycle reset sequence at the cost of a little depth.
A mode register has no reset, because firmware writes it before start. Simulation passes, but formal fails at step 3. Who is right? L1L2
Both, about different things. In formal the unreset mode is free at step 0. So the solver picked the value that enables the block before firmware wrote anything. Simulation started mode at one value per run, and a default run never hit the bad one. Either reset the flop, or write the firmware promise as an initial-state assumption and put it on the sign-off list.
Compare X-optimism, X-pessimism and the way formal handles an unknown start value. L1L2
X-optimism is RTL simulation resolving an unknown too kindly, so a bug hides. For example, an if on X takes the else branch. X-pessimism is gate-level simulation spreading X further than real hardware would, which floods the run with false unknowns. Formal is two-valued and leaves the value free, so it checks both 0 and 1 and reports the one that breaks a property.
A colleague says random initial values in simulation are as good as formal for unreset flops. Break that claim. L1L2
A random initial value is one draw per run. If only a few start values break the rule, most seeds pass. Formal treats the start value as free, so one run checks every value. The solver then picks a value that breaks the property, if one exists.
Follow-upPractise Why Random Initial Values Are Not Enough →What does a formal tool do with the output below, which the RTL assigns as 1'bx? L2
In this flow an explicit x becomes a free value the solver may choose on every cycle. An assertion that the debug output stays low therefore fails, here at step 2. That is useful. A stray x default in a case statement shows up as a real failure, not a silent simulation quirk.
Safety and Liveness Properties5
What is the difference between a safety property and a liveness property, and how does each one fail? L1L2
A safety property says something bad never happens. So a finite trace that reaches the bad state breaks it at a definite step. A liveness property says something good eventually happens. So only an endless trace breaks it: a prefix and a loop where the event never comes. Liveness nearly always needs fairness assumptions, and many teams check a bounded response instead.
QuestionPractise Safety and Liveness Properties →Why does almost every liveness property fail unless you add fairness assumptions? L2
With free inputs, the solver can let the environment stall forever, for example by never raising ready. That endless loop breaks the property. Fairness restricts the search to paths where the environment keeps its promise, such as ready returning infinitely often. Every fairness assumption needs a spec reason and a quick check that it is not vacuous.
Compare deadlock, livelock and starvation. Which of them can a plain bmc run find? L2
Deadlock is a reachable state that nothing can leave, so asserting that state never occurs is safety and bmc finds it. Livelock is a loop of states that keeps moving without progress, and starvation is one requester never served while others are. Those two are liveness; to run them in bmc you bound them with a counter and accept the number you chose.
Follow-upPractise Deadlock, Livelock and Starvation →Compare a liveness check with a bounded-response check such as "ack within 8 cycles of req". L2L3
Bounded response is a safety property: it has a failing step, runs in bmc or prove mode and gives readable traces. Its cost is a number the spec may not give, and picking it too large hides slow paths. Liveness needs no number but needs fairness and a liveness engine. Many sign-offs ship the bounded form with the deadline taken from a measured cover.
Follow-upPractise Liveness vs Bounded Response →A fixed-priority arbiter passes every safety check you wrote. What is it hiding? L2
Starvation: a low-priority requester can wait forever while higher ones keep asking. Safety properties cannot see that, because no single cycle is wrong. You need a liveness property under fairness, or a bounded wait under a named stand-in assumption. Take the bound for the wait from a measured cover.
Follow-upPractise What a Fixed-Priority Arbiter Hides →Your Review Queue
Saved review reminders are coming soon.