High Coverage Concolic Equivalence Checking Pritam Roy pritam roy@mentor.com Sagar Chaki sagar chaki@mentor.com Pankaj Chauhan pankaj chauhan2@mentor.com Abstract—A concolic approach, called SLEC- CF, to check sequential equivalence between a high-level (e.g., C++/SystemC) hardware description and an RTL (e.g., Verilog) is presented. SLEC- CF searches for counterexamples over the possible values of a set of “control signals” in a depth-first lexicographic manner, avoiding values that are unrealizable by any concrete input. In addition, SLEC- CF respects user-specified design constraints during search, thus only producing stimuli that are of relevance to users. It is a superior alternative to random simulations, which produce an overwhelming number of irrelevant stimuli for user- constrained designs, and are therefore of limited effectiveness. To handle complex designs, we present an incremental version of SLEC- CF, which iteratively increases the search depth, and set of control signals, and uses a cache to reuse prior results. We implemented SLEC- CF on top an existing industrial tool for sequential equivalence checking. Experimental results indicate that SLEC- CF clearly outperforms random simulation in terms of coverage achieved. On complex designs, incremental SLEC- CF demonstrates superior ability to achieve good coverage in almost all cases, compared to non-incremental SLEC- CF. I. I NTRODUCTION Hardware equivalence checking [1] has emerged as one of the most promising areas of formal verification in practical settings. With the increasing complexity of hardware designs, there is a clear trend toward high-level synthesis (HLS) [2] – designing hardware using a high-level language (such as C++/SystemC 1 ) and compiling it down to RTL (such as Verilog). In this context, equivalence checking has assumed even greater urgency. The synthesizer performs non-trivial optimizations and transformations over large designs, and it is critical that we assure that it produces functionally equivalent RTL. A number of tools [3] have emerged to tackle this problem. In practice, equivalence checking is often applied to a large system on a per-module basis. Since a module will eventually operate in the context of other modules (its environment) in the final system, its verification must reflect the appropriate environment constraints. This is typically specified by a set of assumptions on legal values of “internal” module variables (such as branch conditions or intermediate results) rather than module “inputs”. To be effective, verification techniques must also respect these environment constraints. In particular, any technique that generates a large number of “invalid” stimuli (which violate environment constraints) for inspection is quickly discarded by users as ineffective. Random testing (fuzzing) [4] is the most prevalent technique used today for generating interesting stimuli for inspection by 1 We’ll henceforth use C++ to mean both. hardware developers. However, it not only has poor coverage for complex designs, but also ignores environment constraints and deluges the user with invalid stimuli. This work was inspired by the need for a better alternative which achieves not only high coverage, but also produces only high-quality valid stimuli. Concolic testing has emerged in recent years as a promising direction for generating testcases with high cover- age. Taking this cue, we propose an approach, called SLEC- CF, which to our knowledge is the first to use concolic exploration for producing valid stimuli in hardware equivalence checking. Specifically, we make three contributions. First, we present SLEC- CF formally. SLEC- CF uses the set of all branch conditions (in the C++) and MUX-select signals (in the RTL) as control signals, rather than the inputs. This is intended to produce higher-quality stimuli since branch con- ditions and MUX-selects represent design corner cases where bugs typically lurk. The core of SLEC- CF is a lexicographic exploration of all control signal (CS) values, using a depth- first search (DFS) strategy. Constraint solving is used to guide the DFS, so that we never explore (unrealizable) values which cannot be reached by any concrete execution. SLEC- CF out- puts all encountered equivalence-falsifying input values (i.e., stimuli) that lead to different outputs between the C++ and the RTL. We show how to incorporate environment constraints into SLEC- CF so that only valid stimuli are generated. We also define a suitable notion of coverage that measures the fraction of CS values explored by SLEC- CF, taking into account both the realizable and unrealizable ones. Second, we present an incremental version of SLEC- CF that iteratively increases the search depth, and the CS set. We also present a caching mechanism to improve the scalability of this incremental approach. In essence, the cache stores results from constraint solver calls that indicate whether a specific CS assignment is realizable. The cache is not a direct lookup since the prior solver invocations involve either a different search depth, or a smaller CS. In addition, the cache works asymmetrically for SAT and UNSAT answers from the solver. For example, if a CS assignment is unrealizable, then so are all its “extensions”, but not necessarily all its “restrictions”. For realizable assignments, the situation is reversed. We use two caches (for SAT and UNSAT answers) that leverage this idea, using an appropriate notion of extensions and restrictions for CS assignments, as the search depth and CS size changes. Finally, we implement SLEC- CF on top of an existing HLS and equivalence checking tool, and evaluate it against random testing using a benchmark derived from industrial examples. Our results indicate that SLEC- CF provides orders 462 978-3-9819263-2-3/DATE19/ c 2019 EDAA