Decision guide
HLS feasibility study
Decide whether a block is a good HLS candidate before committing to implementation.
How to decide whether a legacy Verilog or VHDL block should move to C++ HLS—and how to preserve its contract when it does.
RTL-to-HLS migration is the re-architecture of an existing Verilog or VHDL block as synthesisable C++ or SystemC, followed by generation and verification of replacement RTL. It makes sense when the block is algorithmic, requirements keep changing, or reuse across targets matters. It is not a mechanical translation: the migration succeeds only when behavior, interfaces, timing obligations, state, and memory semantics are made explicit and verified.
A good migration preserves the block's externally observable contract while allowing the internal microarchitecture to change. Before committing a production design, a focused HLS feasibility study can establish whether the selected boundary meets functional, performance, area, tool-flow, and verification needs.
Preserve the contract. Prove the replacement.
The strongest candidates are datapath-dominated blocks whose behavior is naturally described as an algorithm: filters, transforms, codecs, packet calculations, image pipelines, cryptographic kernels, and custom arithmetic. Migration is especially useful when a block needs new modes, must be retargeted, or would benefit from exploring several throughput, latency, and resource trade-offs from one verified source. If the team is new to the method, start with the fundamentals of High-Level Synthesis.
A weak candidate is dominated by asynchronous behavior, clock-domain crossings, technology-specific cells, fine-grained reset sequencing, or cycle-exact protocol control with little algorithmic work. That does not disqualify the whole subsystem. Keep those elements in RTL and migrate a well-bounded computational region. The purpose is maintainability and controlled design exploration, not maximizing the percentage of code written in C++.
The first engineering output is a migration contract. It records what downstream logic and software can observe, including legal inputs, output values, ordering, error behavior, reset behavior, and timing obligations. Five areas deserve explicit treatment:
Verification should answer two different questions: does the C++ model implement the intended function, and does the generated RTL implement that model? The first needs directed corner cases, constrained-random tests where useful, coverage, and comparison with the legacy block. The second uses C-to-RTL co-simulation and, where appropriate, formal or transaction-level equivalence. AMD's official flow describes how C/RTL co-simulation reuses C testbench transactions to check generated RTL.
Cycle-by-cycle sequential equivalence is appropriate only if both implementations share that contract. If the new architecture has a different pipeline depth but identical ordered results, compare transactions with latency-aware scoreboards. Backpressure, stalls, reset during traffic, minimum and maximum values, simultaneous memory events, and long-running state evolution all need dedicated tests. See the fuller HLS verification strategy for planning coverage and sign-off.
A production migration should leave an auditable design package: the migration contract and boundary specification; synthesisable C++ or SystemC; HLS constraints and reproducible build scripts; generated RTL; any integration wrapper; bit-accurate reference model; self-checking tests and vectors; C simulation and C/RTL co-simulation results; synthesis, timing, resource, and implementation reports; known limitations; integration documentation; and a traceable verification matrix. These are typical outputs of a scoped RTL-to-HLS migration engagement.
| Signal | Favors migration | Calls for caution |
|---|---|---|
| Design character | Algorithmic datapath with clear transactions | Dominantly cycle-specific control or asynchronous logic |
| Requirements | Features, targets, or performance points will evolve | Frozen block with no expected reuse or maintenance |
| Verification | Strong regression and observable boundaries | Unknown intent and weak or unavailable tests |
| Technology | Portable operators, memories, and interfaces | Heavy dependence on custom cells or device primitives |
| Team and flow | Ownership of C++, HLS constraints, and generated RTL | No plan for tools, CI, sign-off, or long-term maintenance |
Usually not. The replacement must preserve the agreed externally observable contract. If fixed latency or cycle-level responses are part of that contract, they become explicit HLS constraints or are maintained by a small RTL wrapper. Requiring every internal register transition to match can prevent useful re-architecture.
Not necessarily. A safer first boundary is often an algorithmic datapath with stable interfaces and strong regression tests. Protocol engines, clock-domain crossings, safety mechanisms, or tightly cycle-specific control can remain in RTL and connect to the HLS block through a documented wrapper.
Define the contract first, run shared vectors against the legacy RTL and the C++ model, then use C-to-RTL co-simulation on the generated implementation. Add formal or transaction-level equivalence where appropriate, and complete the normal RTL sign-off checks before replacing the old block.
Yes. Mixed HLS and RTL is a normal architecture. Existing protocol logic, vendor IP, memories, or hand-optimized kernels can remain in RTL, while HLS implements the portions that benefit from algorithm-level design and design-space exploration.
We can assess the boundary, constraints, and verification evidence before you commit to a rewrite.