  Hardware flaws are permanent and potent: hardware cannot be patched once
fabricated, and any flaws may undermine any software executing on top.
Consequently, verification time dominates implementation time. The gold
standard in hardware Design Verification (DV) is concentrated at two extremes:
random dynamic verification and formal verification. Both struggle to root out
the subtle flaws in complex hardware that often manifest as security
vulnerabilities. The root problem with random verification is its undirected
nature, making it inefficient, while formal verification is constrained by the
state-space explosion problem, making it infeasible against complex designs.
What is needed is a solution that is directed, yet under-constrained.
  Instead of making incremental improvements to existing DV approaches, we
leverage the observation that existing software fuzzers already provide such a
solution, and adapt them for hardware DV. Specifically, we translate RTL
hardware to a software model and fuzz that model. The central challenge we
address is how best to mitigate the differences between the hardware execution
model and software execution model. This includes: 1) how to represent test
cases, 2) what is the hardware equivalent of a crash, 3) what is an appropriate
coverage metric, and 4) how to create a general-purpose fuzzing harness for
hardware.
  To evaluate our approach, we fuzz four IP blocks from Google's OpenTitan SoC.
Our experiments reveal a two orders-of-magnitude reduction in run time to
achieve Finite State Machine (FSM) coverage over traditional dynamic
verification schemes. Moreover, with our design-agnostic harness, we achieve
over 88% HDL line coverage in three out of four of our designs -- even without
any initial seeds.
